Skip to content

Commit ee0c0cf

Browse files
committed
Prove remaining case.
1 parent c6a0460 commit ee0c0cf

1 file changed

Lines changed: 108 additions & 36 deletions

File tree

theories/SimplyTypedLambdaCalculus/StrongNormalisation.v

Lines changed: 108 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,38 @@ Proof.
369369
cbn in Hlen. firstorder.
370370
Qed.
371371

372+
Fixpoint update_nth {A : Type} n (l : list A) (a : A) :=
373+
match l with
374+
| nil => nil
375+
| cons x l' => match n with
376+
| 0 => cons a l'
377+
| S n' => cons x (update_nth n' l' a)
378+
end
379+
end.
380+
381+
Lemma update_decr ind n l : ind < length l -> n = List.nth ind l 0 -> n > 0 -> List.list_sum (update_nth ind l (pred n)) < List.list_sum l.
382+
Proof.
383+
intros Hlen Hind Hgt0.
384+
induction l as [| x l IH] in ind, Hlen, Hind, Hgt0 |- *.
385+
- cbn in Hlen. lia.
386+
- cbn in Hlen.
387+
destruct ind as [| ind].
388+
+ cbn in *; subst.
389+
lia.
390+
+ cbn in *. specialize (IH ind).
391+
apply PeanoNat.lt_S_n in Hlen.
392+
firstorder. unfold List.list_sum in H. lia.
393+
Qed.
394+
395+
Lemma update_length {A : Type} (l: list A) n v : length (update_nth n l v) = length l.
396+
Proof.
397+
induction l as [| x l IH] in n |- *.
398+
- destruct n; reflexivity.
399+
- destruct n.
400+
+ cbn. reflexivity.
401+
+ cbn. congruence.
402+
Qed.
403+
372404
Lemma max_steps_list_decr t1 t2 l l' outer :
373405
t1 ~> t2 ->
374406
length l' = length (outer ++ t1 :: l) ->
@@ -382,40 +414,80 @@ Lemma max_steps_list_decr t1 t2 l l' outer :
382414
end -> length l <= n) (List.combine (outer ++ t1 :: l) l') ->
383415
exists l'',
384416
List.list_sum l'' < List.list_sum l'
385-
/\ length l'' = length (outer ++ t1 :: l)
417+
/\ length l'' = length (outer ++ t2 :: l)
386418
/\ List.Forall
387419
(fun p : prod term nat =>
388420
let (t0, n) := p in
389421
forall l0 : list term,
390422
match l0 with
391423
| []%list => True
392424
| (t2 :: _)%list => t0 ~> t2 /\ reduction_sequence l0
393-
end -> length l0 <= n) (List.combine (outer ++ t1 :: l) l'').
425+
end -> length l0 <= n) (List.combine (outer ++ t2 :: l) l'').
394426
Proof.
395427
intros Hstep Hlen Hl'.
396-
assert (List.In t1 (outer ++ t1 :: l)) as Hin.
397-
- auto with datatypes.
398-
- apply List.In_nth with (d := Var 0) in Hin as (ind & Hind & Hin).
399-
rewrite (List.Forall_forall) in Hl'.
400-
pose (List.nth ind l' 0) as n.
401-
assert (List.In (t1, n) (List.combine (outer ++ t1 :: l) l')) as H.
402-
{ assert ((t1, n) = List.nth ind (List.combine (outer ++ t1 :: l) l') (Var 0, 0)) as Hnth.
403-
- rewrite <- Hin.
404-
rewrite List.combine_nth.
405-
+ repeat f_equal.
406-
congruence.
407-
+ rewrite Hlen. congruence.
408-
- rewrite Hnth. apply List.nth_In.
409-
rewrite List.combine_length.
410-
lia.
411-
}
412-
apply Hl' in H.
413-
pose proof (max_steps_decr t1 n H t2 Hstep) as Hdecr.
414-
pose proof (max_steps_nonzero t1 t2 n Hstep H) as Hnz.
415-
416-
(*ideally, we would like to have some kind of list update function here with the desired properties. We don't.*)
417-
(*induction on outer won't work: we don't get from List.nth ind (t1 :: l) _ = t1 that ind = 0. *)
418-
Admitted.
428+
pose (length outer) as ind.
429+
assert (ind < length (outer ++ t1 :: l)) as Hind.
430+
{
431+
clear.
432+
induction outer; cbn in *; lia.
433+
}
434+
assert (List.nth ind (outer ++ t1 :: l) (Var 0) = t1) as Hin.
435+
{
436+
clear.
437+
induction outer; cbn in *.
438+
- reflexivity.
439+
- assumption.
440+
}
441+
rewrite (List.Forall_forall) in Hl'.
442+
pose (List.nth ind l' 0) as n.
443+
assert (List.In (t1, n) (List.combine (outer ++ t1 :: l) l')) as H.
444+
{ assert ((t1, n) = List.nth ind (List.combine (outer ++ t1 :: l) l') (Var 0, 0)) as Hnth.
445+
- rewrite <- Hin.
446+
rewrite List.combine_nth.
447+
+ repeat f_equal.
448+
congruence.
449+
+ rewrite Hlen. congruence.
450+
- rewrite Hnth. apply List.nth_In.
451+
rewrite List.combine_length.
452+
lia.
453+
}
454+
apply Hl' in H.
455+
pose proof (max_steps_decr t1 n H t2 Hstep) as Hdecr.
456+
pose proof (max_steps_nonzero t1 t2 n Hstep H) as Hnz.
457+
458+
exists (update_nth ind l' (pred n)).
459+
split. 1: {
460+
apply update_decr.
461+
- lia.
462+
- reflexivity.
463+
- assumption.
464+
}
465+
split. 1: {
466+
rewrite update_length.
467+
rewrite Hlen.
468+
clear.
469+
induction outer; cbn.
470+
- reflexivity.
471+
- congruence.
472+
}
473+
rewrite <- List.Forall_forall in Hl'.
474+
clear - Hdecr Hl' Hlen.
475+
unfold ind in *.
476+
477+
induction outer in l', Hl', n, Hlen, Hdecr |- *.
478+
- cbn in *. destruct l'.
479+
+ constructor.
480+
+ constructor.
481+
* exact Hdecr.
482+
* inversion Hl'; subst. assumption.
483+
- destruct l'; cbn in *.
484+
+ congruence.
485+
+ inversion Hl'.
486+
constructor.
487+
* assumption.
488+
* apply IHouter; try assumption.
489+
now inversion Hlen.
490+
Qed.
419491

420492
(* Lemma 3.2.1 statement (3) for the base case, where the entire term is of some atomic type.
421493
Formalizing this proof is difficult:
@@ -530,17 +602,17 @@ Proof.
530602
rewrite (nested_app_app).
531603
destruct Hl' as [Hl'1 Hl'2].
532604
pose proof (max_steps_list_decr t1 t' l l' outer Hstep Hl'1 Hl'2) as (l'' & Hdecr & Hl'').
605+
constructor.
533606
eapply IH.
534-
2: exact Hsn.
535-
2: exact Hsnu.
536-
2, 3: eassumption.
537-
3: reflexivity.
538-
3: {
539-
clear - Hstep.
540-
induction outer; now constructor.
541-
}
542-
2: exact Hl''.
543-
lia.
607+
3: exact Hsnu.
608+
3: exact Hnt.
609+
3: exact Hnu.
610+
4: reflexivity.
611+
3: exact Hl''.
612+
1: lia.
613+
eapply SN_inverted. 1: exact Hsn.
614+
clear - Hstep.
615+
induction outer; now constructor.
544616
- destruct l; cbn in Heqtrm; congruence.
545617
Qed.
546618

@@ -731,4 +803,4 @@ Proof.
731803
intros.
732804
apply reducible_var with Γ.
733805
now apply Typing_Var.
734-
Qed
806+
Qed.

0 commit comments

Comments
 (0)