(* *********************************************************************)
(*                                                                     *)
(*              The Compcert verified compiler                         *)
(*                                                                     *)
(*          Jacques-Henri Jourdan, INRIA Paris-Rocquencourt            *)
(*                                                                     *)
(*  Copyright Institut National de Recherche en Informatique et en     *)
(*  Automatique.  All rights reserved.  This file is distributed       *)
(*  under the terms of the GNU General Public License as published by  *)
(*  the Free Software Foundation, either version 2 of the License, or  *)
(*  (at your option) any later version.  This file is also distributed *)
(*  under the terms of the INRIA Non-Commercial License Agreement.     *)
(*                                                                     *)
(* *********************************************************************)
Require Grammar.
Require Automaton.
Require Interpreter.
Module Make(Import A:Automaton.T) (Import Inter:Interpreter.T A).
(** * Correctness of the interpreter **)
(** We prove that, in any case, if the interpreter accepts returning a semantic value, then this is a semantic value of the input **)
Section Init.
Variable init:initstate.
(** [word_has_stack_semantics] relates a word with a state, 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)
(semantic_valuet:_),
inhabited (parse_tree (last_symb_of_non_init_state s) wordt semantic_valuet) ->
word_has_stack_semantics
(wordq++wordt) (existT noninitstate_type s semantic_valuet::stackq).

(** [reduce_step] preserves the invariant **)
Lemma reduce_step_invariant (stack:stack) (prod:production):
forall word buffer, word_has_stack_semantics word stack ->
match reduce_step init stack prod buffer with
| OK (Accept_sr sem buffer_new) =>
buffer = buffer_new /\
inhabited (parse_tree (NT (start_nt init)) word sem)
| OK (Progress_sr stack_new buffer_new) =>
buffer = buffer_new /\
word_has_stack_semantics word stack_new
| Err | OK Fail_sr => True
end.