11(* Distributed under the terms of the MIT license. *)
22Set Warnings "-notation-overridden".
33
4- From Coq Require Import Arith Bool List Program .
4+ From Coq Require Import Arith Bool List Program Lia .
55From Equations Require Import Equations.
66From MetaCoq.Template Require Import config utils.
77From MetaCoq.Erasure Require Import EAst EAstUtils ELiftSubst ECSubst ETyping.
@@ -52,12 +52,11 @@ Definition cunfold_fix (mfix : mfixpoint term) (idx : nat) :=
5252 | None => None
5353 end .
5454
55- Definition isStuckFix t args :=
55+ Definition isStuckFix t ( args : list term) :=
5656 match t with
5757 | tFix mfix idx =>
5858 match cunfold_fix mfix idx with
59- | Some (narg, fn) =>
60- ~~ is_nth_constructor_app_or_box narg args
59+ | Some (narg, fn) => #|args| <=? narg
6160 | None => false
6261 end
6362 | _ => false
@@ -114,12 +113,10 @@ Section Wcbv.
114113 eval (tCase (ind, pars) discr brs) res
115114
116115 (** Fix unfolding, with guard *)
117- | eval_fix f mfix idx argsv a av narg fn res :
116+ | eval_fix f mfix idx argsv a av fn res :
118117 eval f (mkApps (tFix mfix idx) argsv) ->
119118 eval a av ->
120- cunfold_fix mfix idx = Some (narg, fn) ->
121- #|argsv| = narg ->
122- is_constructor_app_or_box av ->
119+ cunfold_fix mfix idx = Some (#|argsv|, fn) ->
123120 eval (tApp (mkApps fn argsv) av) res ->
124121 eval (tApp f a) res
125122
@@ -128,7 +125,7 @@ Section Wcbv.
128125 eval f (mkApps (tFix mfix idx) argsv) ->
129126 eval a av ->
130127 cunfold_fix mfix idx = Some (narg, fn) ->
131- (#|argsv| <> narg \/ (#|argsv| = narg /\ ~~is_constructor_app_or_box av) ) ->
128+ (#|argsv| < narg) ->
132129 eval (tApp f a) (tApp (mkApps (tFix mfix idx) argsv) av)
133130
134131 (** CoFix-case unfolding *)
@@ -285,24 +282,13 @@ Section Wcbv.
285282 apply (value_stuck_fix _ [av]); [easy|].
286283 cbn.
287284 destruct (cunfold_fix mfix idx) as [(? & ?)|]; [|easy].
288- noconf H1.
289- destruct H2 as [|(<- & ?)]; [|easy].
290- unfold is_nth_constructor_app_or_box.
291- now rewrite (proj2 (nth_error_None _ _));
292- cbn in *.
285+ noconf H1. destruct narg; auto. lia.
293286 + easy.
294287 + eapply value_stuck_fix; [now apply Forall_app_inv|].
295288 unfold isStuckFix in *.
296289 destruct (cunfold_fix mfix idx) as [(? & ?)|]; [|easy].
297- noconf H1.
298- unfold is_nth_constructor_app_or_box in *.
299- destruct H2 as [|(<- & ?)]; [|now rewrite nth_error_snoc].
300- destruct (Nat.ltb_spec #|argsv| narg).
301- * rewrite (proj2 (nth_error_None _ _)); [|easy].
302- rewrite app_length.
303- cbn.
304- easy.
305- * now rewrite nth_error_app1.
290+ noconf H1. rewrite app_length; simpl.
291+ eapply Nat.leb_le. lia.
306292
307293 - destruct (mkApps_elim f' [a']).
308294 eapply value_mkApps_inv in IHeval1 => //.
@@ -320,15 +306,14 @@ Section Wcbv.
320306 rewrite orb_true_r orb_true_l in H0. easy.
321307 Qed .
322308
323- Lemma closed_unfold_fix_cunfold_eq mfix idx :
309+ Lemma closed_fix_substl_subst_eq { mfix idx d} :
324310 closed (tFix mfix idx) ->
325- unfold_fix mfix idx = cunfold_fix mfix idx.
311+ nth_error mfix idx = Some d ->
312+ subst0 (fix_subst mfix) (dbody d) = substl (fix_subst mfix) (dbody d).
326313 Proof .
327- unfold unfold_fix, cunfold_fix.
328- destruct (nth_error mfix idx) eqn:Heq => //.
329314 move=> /= Hf; f_equal; f_equal.
330315 have clfix : All (closedn 0) (fix_subst mfix).
331- { clear Heq d idx.
316+ { clear idx.
332317 solve_all.
333318 unfold fix_subst.
334319 move: #|mfix| => n.
@@ -340,11 +325,22 @@ Section Wcbv.
340325 now rewrite subst_empty.
341326 move=> Ha; depelim Ha.
342327 simpl in *.
328+ intros hnth.
343329 rewrite -IHfix_subst => //.
344330 rewrite (subst_app_decomp [_]). simpl.
345331 f_equal. rewrite lift_closed // closed_subst //.
346332 Qed .
347333
334+ Lemma closed_unfold_fix_cunfold_eq mfix idx :
335+ closed (tFix mfix idx) ->
336+ unfold_fix mfix idx = cunfold_fix mfix idx.
337+ Proof .
338+ unfold unfold_fix, cunfold_fix.
339+ destruct (nth_error mfix idx) eqn:Heq => //.
340+ intros cl; f_equal; f_equal.
341+ now rewrite (closed_fix_substl_subst_eq cl).
342+ Qed .
343+
348344 Lemma closed_unfold_cofix_cunfold_eq mfix idx :
349345 closed (tCoFix mfix idx) ->
350346 unfold_cofix mfix idx = cunfold_cofix mfix idx.
@@ -390,6 +386,106 @@ Qed.
390386
391387Derive NoConfusionHom for EAst.global_decl.
392388
389+
390+ Lemma Forall_Forall2_refl :
391+ forall (A : Type) (R : A -> A -> Prop) (l : list A),
392+ Forall (fun x : A => R x x) l -> Forall2 R l l.
393+ Proof .
394+ induction 1; constructor; auto.
395+ Qed .
396+
397+ Lemma value_head_spec_impl t :
398+ implb (value_head t) (~~ (isLambda t || isFixApp t || isBox t)).
399+ Proof .
400+ destruct t; simpl; intuition auto; eapply implybT.
401+ Qed .
402+
403+ Derive Signature for Forall.
404+
405+ Lemma eval_stuck_fix args argsv mfix idx :
406+ Forall2 eval args argsv ->
407+ isStuckFix (tFix mfix idx) argsv ->
408+ eval (mkApps (tFix mfix idx) args) (mkApps (tFix mfix idx) argsv).
409+ Proof .
410+ revert argsv.
411+ induction args as [|a args IH] using MCList.rev_ind;
412+ intros argsv all stuck.
413+ - apply Forall2_length in all.
414+ destruct argsv; [|easy].
415+ now apply eval_atom.
416+ - destruct argsv as [|? ? _] using MCList.rev_ind;
417+ [apply Forall2_length in all; rewrite app_length in all; now cbn in *|].
418+ apply Forall2_app_r in all as (all & ev_a).
419+ rewrite <- !mkApps_nested.
420+ cbn in *.
421+ destruct (cunfold_fix mfix idx) as [(? & ?)|] eqn:cuf; [|easy].
422+ eapply eval_fix_value.
423+ + apply IH; [easy|].
424+ destruct (cunfold_fix mfix idx) as [(? & ?)|]; [|easy].
425+ rewrite app_length /= in stuck.
426+ eapply Nat.leb_le in stuck. eapply Nat.leb_le. lia.
427+ + easy.
428+ + easy.
429+ + rewrite app_length /= in stuck.
430+ eapply Nat.leb_le in stuck; lia.
431+ Qed .
432+
433+ Lemma stuck_fix_value_inv argsv mfix idx narg fn :
434+ value (mkApps (tFix mfix idx) argsv) ->
435+ cunfold_fix mfix idx = Some (narg, fn) ->
436+ (Forall value argsv /\ isStuckFix (tFix mfix idx) argsv).
437+ Proof .
438+ remember (mkApps (tFix mfix idx) argsv) as tfix.
439+ intros hv; revert Heqtfix.
440+ induction hv using value_values_ind; intros eq; subst.
441+ unfold atom in H. destruct argsv using rev_case => //.
442+ split; auto. simpl. simpl in H. rewrite H0 //.
443+ rewrite -mkApps_nested /= in H. depelim H.
444+ solve_discr => //.
445+ solve_discr.
446+ Qed .
447+
448+ Lemma stuck_fix_value_args argsv mfix idx narg fn :
449+ value (mkApps (tFix mfix idx) argsv) ->
450+ cunfold_fix mfix idx = Some (narg, fn) ->
451+ #|argsv| <= narg.
452+ Proof .
453+ intros val unf.
454+ eapply stuck_fix_value_inv in val; eauto.
455+ destruct val.
456+ simpl in H0. rewrite unf in H0.
457+ now eapply Nat.leb_le in H0.
458+ Qed .
459+
460+ Lemma value_final e : value e -> eval e e.
461+ Proof .
462+ induction 1 using value_values_ind; simpl; auto using value.
463+ - apply Forall_Forall2_refl in H1 as H2.
464+ move/implyP: (value_head_spec_impl t).
465+ move/(_ H) => Ht.
466+ induction l using rev_ind. simpl.
467+ destruct t; try discriminate.
468+ * repeat constructor.
469+ * repeat constructor.
470+ * rewrite -mkApps_nested.
471+ eapply Forall_app in H0 as [Hl Hx]. depelim Hx.
472+ eapply Forall_app in H1 as [Hl' Hx']. depelim Hx'.
473+ eapply Forall2_app_inv_r in H2 as [Hl'' [Hx'' [? [? ?]]]].
474+ depelim H3. depelim H4.
475+ eapply eval_app_cong; auto.
476+ eapply IHl; auto.
477+ now eapply Forall_Forall2.
478+ destruct l using rev_ind; auto.
479+ eapply value_head_nApp in H.
480+ rewrite isFixApp_mkApps => //.
481+ rewrite -mkApps_nested; simpl.
482+ rewrite orb_false_r.
483+ destruct t; auto.
484+ - destruct f; try discriminate.
485+ apply Forall_Forall2_refl in H0.
486+ now apply eval_stuck_fix.
487+ Qed .
488+
393489Unset SsrRewrite.
394490Lemma eval_deterministic {t v v'} :
395491 eval t v ->
@@ -440,27 +536,26 @@ Proof.
440536 + apply IHev1 in ev'1.
441537 apply mkApps_eq_inj in ev'1; try easy.
442538 depelim ev'1.
443- noconf H2.
539+ noconf H1; noconf H2.
444540 subst.
445541 apply IHev2 in ev'2; subst.
446- rewrite H4 in H.
542+ noconf H0.
543+ rewrite H2 in H.
447544 now noconf H.
448545 + apply IHev1 in ev'1.
449546 apply mkApps_eq_inj in ev'1; try easy.
450547 depelim ev'1.
548+ noconf H1.
451549 noconf H2.
452- noconf H3.
453550 apply IHev2 in ev'2.
454- subst.
455- rewrite H4 in H.
456- noconf H.
457- destruct H5 as [|(_ & ?)]; [easy|].
458- now apply negb_true_iff in H.
551+ subst. noconf H0.
552+ rewrite H2 in H.
553+ noconf H. lia.
459554 + apply IHev1 in ev'1.
460555 subst.
461- rewrite isFixApp_mkApps in H2 by easy.
556+ rewrite isFixApp_mkApps in H0 by easy.
462557 cbn in *.
463- now rewrite orb_true_r in H2 .
558+ now rewrite orb_true_r in H0 .
464559 + easy.
465560 - depelim ev'.
466561 + apply IHev1 in ev'1; solve_discr.
@@ -471,9 +566,7 @@ Proof.
471566 noconf ev'1.
472567 subst.
473568 rewrite H1 in H.
474- noconf H.
475- destruct H0 as [|(? & ?)]; [easy|].
476- now apply negb_true_iff in H0.
569+ noconf H. lia.
477570 + apply IHev1 in ev'1.
478571 apply IHev2 in ev'2.
479572 now apply mkApps_eq_inj in ev'1 as (ev'1 & <-).
0 commit comments