Section Init.
Variable init:initstate.
(** [word_has_stack_semantics] relates a word with a stack, stating that the word is a concatenation of words that have the semantic values stored in the stack. **)
Inductive word_has_stack_semantics:
forall (word:list token) (stack:stack), Prop :=
| Nil_stack_whss: word_has_stack_semantics [] []
| Cons_stack_whss:
forall (wordq:list token) (stackq:stack),
word_has_stack_semantics wordq stackq ->
forall (wordt:list token) (s:noninitstate)
(pt:parse_tree (last_symb_of_non_init_state s) wordt),
word_has_stack_semantics
(wordq++wordt) (existT noninitstate_type s (pt_sem pt)::stackq).

(** [step] preserves the invariant **)
Lemma step_invariant stk word buffer safe Hi :
word_has_stack_semantics word stk ->
match step safe init stk buffer Hi with
| Accept_sr sem buffer_new =>
exists word_new (pt:parse_tree (NT (start_nt init)) word_new),
(word ++ buffer = word_new ++ buffer_new)%buf /\
pt_sem pt = sem
| Progress_sr stk_new buffer_new =>
exists word_new,
(word ++ buffer = word_new ++ buffer_new)%buf /\
word_has_stack_semantics word_new stk_new
| Fail_sr => True
end.