@@ -642,27 +642,101 @@ Fixpoint free_vars (e : phr_expr) : list string :=
642642 | EIn e1 e2 => free_vars e1 ++ free_vars e2
643643 end .
644644
645- (** Totality / progress-to-a-value.
645+ (** Totality / progress-to-a-value: a well-typed closed expression always
646+ evaluates to a value (the language has no loops or recursion).
646647
647- NOTE (honesty): this is the one safety obligation in this file that is NOT
648- yet mechanized. It is stated here as an explicit [Admitted] obligation, not
649- a hidden gap. The ORIGINAL statement (closedness of the value environment
650- alone implies evaluation) is FALSE — e.g. [EBinOp OpAdd (ELit (VBool true))
648+ NOTE: the ORIGINAL statement required only that the value environment cover
649+ [free_vars e], which is FALSE — e.g. [EBinOp OpAdd (ELit (VBool true))
651650 (ELit (VInt 1))] is closed but has no applicable evaluation rule. The
652- correct statement requires WELL-TYPEDNESS: a closed, well-typed expression
653- evaluates to a value (the language has no loops or recursion). The full
654- proof is an induction on the typing derivation using the canonical-forms
655- lemmas to pin each operand's value shape; it is left open here.
656-
657- Nothing below depends on [totality]; the safety core ([preservation],
658- [eval_deterministic], [type_safety], [phr_type_eq_dec], [subtype_trans],
659- [no_system_calls]) is fully proved and axiom-free. *)
651+ correct hypothesis is WELL-TYPEDNESS; and since [[] ⊢ e ∈ τ] already forces
652+ [e] to be closed (there is no binding form, so [EVar] is untypable here),
653+ the value-environment hypothesis is redundant and dropped. The proof is an
654+ induction on [e] that uses [preservation] + the canonical value shapes to
655+ pin each operand. [ρ] is arbitrary precisely because [e] is closed. *)
660656Theorem totality : forall e τ ρ,
661- [] ⊢ e ∈ τ ->
662- (forall x, In x (free_vars e) -> exists v, val_lookup x ρ = Some v) ->
663- exists v, ρ ⊢ e ⇓ v.
657+ [] ⊢ e ∈ τ -> exists v, ρ ⊢ e ⇓ v.
664658Proof .
665- Admitted .
659+ intros e; induction e as
660+ [ p | s | b e1 IHe1 e2 IHe2 | u e IHe
661+ | e1 IHe1 e2 IHe2 e3 IHe3 | e IHe f | e1 IHe1 e2 IHe2 ];
662+ intros τ ρ Ht.
663+ - (* ELit *) exists p. constructor.
664+ - (* EVar: untypable in the empty context *)
665+ inversion Ht; subst.
666+ match goal with H : lookup _ [] = Some _ |- _ => simpl in H; discriminate H end.
667+ - (* EBinOp: evaluate the left operand once, up front *)
668+ inversion Ht; subst;
669+ match goal with Ha : has_type [] e1 _ |- _ =>
670+ destruct (IHe1 _ ρ Ha) as [v1 Hv1];
671+ pose proof (preservation _ _ _ _ Ha Hv1) as T1
672+ end.
673+ + (* Add *) match goal with Hb : has_type [] e2 _ |- _ =>
674+ destruct (IHe2 _ ρ Hb) as [v2 Hv2]; pose proof (preservation _ _ _ _ Hb Hv2) as T2 end;
675+ inversion T1; subst; inversion T2; subst; eexists; apply E_Add; eassumption.
676+ + (* Sub *) match goal with Hb : has_type [] e2 _ |- _ =>
677+ destruct (IHe2 _ ρ Hb) as [v2 Hv2]; pose proof (preservation _ _ _ _ Hb Hv2) as T2 end;
678+ inversion T1; subst; inversion T2; subst; eexists; apply E_Sub; eassumption.
679+ + (* Mul *) match goal with Hb : has_type [] e2 _ |- _ =>
680+ destruct (IHe2 _ ρ Hb) as [v2 Hv2]; pose proof (preservation _ _ _ _ Hb Hv2) as T2 end;
681+ inversion T1; subst; inversion T2; subst; eexists; apply E_Mul; eassumption.
682+ + (* And: short-circuit on the left guard *)
683+ inversion T1; subst;
684+ match goal with Hg : _ ⊢ e1 ⇓ VBool ?bb |- _ => destruct bb end.
685+ * match goal with Hb : has_type [] e2 _ |- _ =>
686+ destruct (IHe2 _ ρ Hb) as [v2 Hv2]; pose proof (preservation _ _ _ _ Hb Hv2) as T2 end;
687+ inversion T2; subst; eexists; apply E_And_True; eassumption.
688+ * eexists; apply E_And_False; eassumption.
689+ + (* Or: short-circuit on the left guard *)
690+ inversion T1; subst;
691+ match goal with Hg : _ ⊢ e1 ⇓ VBool ?bb |- _ => destruct bb end.
692+ * eexists; apply E_Or_True; eassumption.
693+ * match goal with Hb : has_type [] e2 _ |- _ =>
694+ destruct (IHe2 _ ρ Hb) as [v2 Hv2]; pose proof (preservation _ _ _ _ Hb Hv2) as T2 end;
695+ inversion T2; subst; eexists; apply E_Or_False; eassumption.
696+ + (* Eq: no value-shape constraint *)
697+ match goal with Hb : has_type [] e2 _ |- _ =>
698+ destruct (IHe2 _ ρ Hb) as [v2 Hv2] end;
699+ eexists; apply E_Eq; eassumption.
700+ + (* Lt *) match goal with Hb : has_type [] e2 _ |- _ =>
701+ destruct (IHe2 _ ρ Hb) as [v2 Hv2]; pose proof (preservation _ _ _ _ Hb Hv2) as T2 end;
702+ inversion T1; subst; inversion T2; subst; eexists; apply E_Lt; eassumption.
703+ - (* EUnOp *)
704+ inversion Ht; subst;
705+ match goal with Ha : has_type [] e _ |- _ =>
706+ destruct (IHe _ ρ Ha) as [v Hv]; pose proof (preservation _ _ _ _ Ha Hv) as T end;
707+ inversion T; subst.
708+ + eexists; apply E_Not; eassumption.
709+ + eexists; apply E_Neg; eassumption.
710+ - (* EIf: branch on the guard value *)
711+ inversion Ht; subst.
712+ match goal with Hc : has_type [] e1 _ |- _ =>
713+ destruct (IHe1 _ ρ Hc) as [v1 Hv1]; pose proof (preservation _ _ _ _ Hc Hv1) as T1 end.
714+ inversion T1; subst.
715+ match goal with Hg : _ ⊢ e1 ⇓ VBool ?bb |- _ => destruct bb end.
716+ + match goal with Ht2 : has_type [] e2 _ |- _ =>
717+ destruct (IHe2 _ ρ Ht2) as [v2 Hv2] end; exists v2; apply E_If_True; assumption.
718+ + match goal with Ht3 : has_type [] e3 _ |- _ =>
719+ destruct (IHe3 _ ρ Ht3) as [v3 Hv3] end; exists v3; apply E_If_False; assumption.
720+ - (* EField: the field exists in the (well-typed) record value *)
721+ inversion Ht; subst.
722+ match goal with Hr : has_type [] e (TRecord ?ff), Hin : In (f, τ) ?ff |- _ =>
723+ destruct (IHe _ ρ Hr) as [v Hv]; pose proof (preservation _ _ _ _ Hr Hv) as T;
724+ inversion T; subst;
725+ match goal with Hbody : forall a t, In (a, t) ff -> _ |- _ =>
726+ destruct (Hbody f τ Hin) as [w [Hlk Hwt]]
727+ end
728+ end.
729+ exists w. eapply E_Field; eassumption.
730+ - (* EIn: the right operand is a list value *)
731+ inversion Ht; subst.
732+ match goal with
733+ Ha : has_type [] e1 _, Hb : has_type [] e2 (TList _) |- _ =>
734+ destruct (IHe1 _ ρ Ha) as [v1 Hv1];
735+ destruct (IHe2 _ ρ Hb) as [v2 Hv2];
736+ pose proof (preservation _ _ _ _ Hb Hv2) as T2
737+ end.
738+ inversion T2; subst. eexists. apply E_In; eassumption.
739+ Qed .
666740
667741(** * 16. Type Safety Corollary *)
668742
0 commit comments