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).

(** [reduce_step] preserves the invariant **)
Lemma reduce_step_invariant (stk:stack) (prod:production) Hv Hi word buffer :
word_has_stack_semantics word stk ->
match reduce_step init stk prod buffer Hv Hi with
| Accept_sr sem buffer_new =>
exists pt : parse_tree (NT (start_nt init)) word,
buffer = buffer_new /\ pt_sem pt = sem
| Progress_sr stk' buffer_new =>
buffer = buffer_new /\ word_has_stack_semantics word stk'
| Fail_sr => True
end.