Proof with eauto.
intros.
destruct X.
inversion H; subst.
apply TerminalSet.singleton_2, compare_refl...
apply first_stable...
intros.
destruct X.
congruence.
simpl.
case_eq wordt; intros.
erewrite nullable_correct...
apply TerminalSet.union_3.
subst...
rewrite H0 in *; inversion H; destruct H2.
destruct (nullable_symb head_symbolt)...
apply TerminalSet.union_2...
Qed.
Variable init: initstate.
Variable full_word: list token.
Variable buffer_end: Stream token.
Variable full_sem: symbol_semantic_type (NT (start_nt init)).
Inductive pt_zipper:
forall (hole_symb:symbol) (hole_word:list token)
(hole_sem:symbol_semantic_type hole_symb), Type :=
| Top_ptz:
pt_zipper (NT (start_nt init)) (full_word) (full_sem)
| Cons_ptl_ptz:
forall {head_symbolt:symbol}
{wordt:list token}
{semantic_valuet:symbol_semantic_type head_symbolt},
forall {head_symbolsq:list symbol}
{wordq:list token}
{semantic_valuesq:tuple (map symbol_semantic_type head_symbolsq)},
parse_tree_list head_symbolsq wordq semantic_valuesq ->
ptl_zipper (head_symbolt::head_symbolsq) (wordt++wordq)
(semantic_valuet,semantic_valuesq) ->
pt_zipper head_symbolt wordt semantic_valuet
with ptl_zipper:
forall (hole_symbs:list symbol) (hole_word:list token)
(hole_sems:tuple (map symbol_semantic_type hole_symbs)), Type :=
| Non_terminal_pt_ptlz:
forall {p:production} {word:list token}
{semantic_values:tuple (map symbol_semantic_type (rev (prod_rhs_rev p)))},
pt_zipper (NT (prod_lhs p)) word (uncurry (prod_action p) semantic_values) ->
ptl_zipper (rev (prod_rhs_rev p)) word semantic_values
| Cons_ptl_ptlz:
forall {head_symbolt:symbol}
{wordt:list token}
{semantic_valuet:symbol_semantic_type head_symbolt},
parse_tree head_symbolt wordt semantic_valuet ->
forall {head_symbolsq:list symbol}
{wordq:list token}
{semantic_valuesq:tuple (map symbol_semantic_type head_symbolsq)},
ptl_zipper (head_symbolt::head_symbolsq) (wordt++wordq)
(semantic_valuet,semantic_valuesq) ->
ptl_zipper head_symbolsq wordq semantic_valuesq.
Fixpoint ptlz_cost {hole_symbs hole_word hole_sems}
(ptlz:ptl_zipper hole_symbs hole_word hole_sems) :=
match ptlz with
| Non_terminal_pt_ptlz ptz =>
ptz_cost ptz
| Cons_ptl_ptlz pt ptlz' =>
ptlz_cost ptlz'
end
with ptz_cost {hole_symb hole_word hole_sem}
(ptz:pt_zipper hole_symb hole_word hole_sem) :=
match ptz with
| Top_ptz => 0
| Cons_ptl_ptz ptl ptlz' =>
1 + ptl_size ptl + ptlz_cost ptlz'
end.
Inductive pt_dot: Type :=
| Reduce_ptd: ptl_zipper [] [] () -> pt_dot
| Shift_ptd:
forall (term:terminal) (sem: symbol_semantic_type (T term))
{symbolsq wordq semsq},
parse_tree_list symbolsq wordq semsq ->
ptl_zipper (T term::symbolsq) (existT (fun t => symbol_semantic_type (T t)) term sem::wordq) (sem, semsq) ->
pt_dot.
Definition ptd_cost (ptd:pt_dot) :=
match ptd with
| Reduce_ptd ptlz => ptlz_cost ptlz
| Shift_ptd _ _ ptl ptlz => 1 + ptl_size ptl + ptlz_cost ptlz
end.
Fixpoint ptlz_buffer {hole_symbs hole_word hole_sems}
(ptlz:ptl_zipper hole_symbs hole_word hole_sems): Stream token :=
match ptlz with
| Non_terminal_pt_ptlz ptz =>
ptz_buffer ptz
| Cons_ptl_ptlz _ ptlz' =>
ptlz_buffer ptlz'
end
with ptz_buffer {hole_symb hole_word hole_sem}
(ptz:pt_zipper hole_symb hole_word hole_sem): Stream token :=
match ptz with
| Top_ptz => buffer_end
| @Cons_ptl_ptz _ _ _ _ wordq _ ptl ptlz' =>
wordq++ptlz_buffer ptlz'
end.
Definition ptd_buffer (ptd:pt_dot) :=
match ptd with
| Reduce_ptd ptlz => ptlz_buffer ptlz
| @Shift_ptd term sem _ wordq _ _ ptlz =>
Cons (existT (fun t => symbol_semantic_type (T t)) term sem)
(wordq ++ ptlz_buffer ptlz)
end.
Fixpoint ptlz_prod {hole_symbs hole_word hole_sems}
(ptlz:ptl_zipper hole_symbs hole_word hole_sems): production :=
match ptlz with
| @Non_terminal_pt_ptlz prod _ _ _ => prod
| Cons_ptl_ptlz _ ptlz' =>
ptlz_prod ptlz'
end.
Fixpoint ptlz_past {hole_symbs hole_word hole_sems}
(ptlz:ptl_zipper hole_symbs hole_word hole_sems): list symbol :=
match ptlz with
| Non_terminal_pt_ptlz _ => []
| @Cons_ptl_ptlz s _ _ _ _ _ _ ptlz' => s::ptlz_past ptlz'
end.

(* Specifications: *)
Lemma ptlz_past_ptlz_prod:
forall hole_symbs hole_word hole_sems
(ptlz:ptl_zipper hole_symbs hole_word hole_sems),
rev_append hole_symbs (ptlz_past ptlz) = prod_rhs_rev (ptlz_prod ptlz).