proof/: model the TIB name-parse primitive, close it into CONSTANT's full model

input_buffer/input_length/input_pos (include/vm.h:415-417) turned out to
be plain per-VM array/scalar fields, not host pointers -- unlike almost
every other input-adjacent gap in this suite. vm_parse_word (src/vm.c:
137-160) is a pure whitespace-delimited scan over them, now modelled as
forth_parse_word in StarForth_Base.thy (is_ws + dropWhile/takeWhile,
faithful to the C's skip-then-copy-with-truncation loop, including that
input_pos only advances past a truncated token by what was actually
copied, matching the C's `len < max_len - 1` bound exactly).

dict_insert_entry (added last session) now takes the entry's name as a
parameter instead of hardcoding the empty string. forth_constant_full
composes forth_parse_word with dict_insert_entry end-to-end as a worked
example: CONSTANT's real order (stack-underflow guard -> pop value ->
parse name -> vm_create_word) is modelled in full up to the data-field
write, which remains the one still-open gap. The other four entry-half
definitions (:/CREATE/VARIABLE/DEFER) take the parsed name as a caller
parameter for now rather than repeating the same composition four more
times in one pass.

Full suite (54 theories) verifies green.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Robert Allan James
2026-08-14 22:53:11 -04:00
co-authored by Claude Sonnet 5
parent cc46cf83f1
commit 1aca77d55c
4 changed files with 229 additions and 54 deletions
+5 -5
View File
@@ -73,18 +73,18 @@ lemma is_guard_rest_not_modelled: True
VARIABLE/CONSTANT, reusing `dict_insert_entry 0` directly. NOT modelled:
the name parse (TIB gap), and the DF zero-init that follows (gap b). *)
definition forth_defer_entry_half :: "bool \<Rightarrow> vm_state \<Rightarrow> vm_state" where
"forth_defer_entry_half pinned_conflict vm = dict_insert_entry 0 pinned_conflict vm"
definition forth_defer_entry_half :: "string \<Rightarrow> bool \<Rightarrow> vm_state \<Rightarrow> vm_state" where
"forth_defer_entry_half name pinned_conflict vm = dict_insert_entry name 0 pinned_conflict vm"
lemma defer_entry_half_populates_dictionary:
assumes "\<not> pinned_conflict"
shows "\<exists>e. dictionary (forth_defer_entry_half pinned_conflict vm) (word_id_next vm) = Some e
\<and> de_flags e = 0"
shows "\<exists>e. dictionary (forth_defer_entry_half name pinned_conflict vm) (word_id_next vm) = Some e
\<and> de_name e = name \<and> de_flags e = 0"
using assms by (simp add: forth_defer_entry_half_def dict_insert_entry_def Let_def)
lemma defer_entry_half_pinned_conflict_errors:
assumes "pinned_conflict"
shows "vm_error (forth_defer_entry_half pinned_conflict vm)"
shows "vm_error (forth_defer_entry_half name pinned_conflict vm)"
using assms by (simp add: forth_defer_entry_half_def dict_insert_entry_def set_error_def)
lemma defer_not_modelled: True \<comment> \<open>DEFER beyond the entry-creation half: name parse (TIB gap) + DF zero-init (gap b). See forth_defer_entry_half above for what IS now modelled.\<close>