Finish a draft of the UCC evaluator article

This commit is contained in:
Danila Fedorin 2021-11-28 16:50:28 -08:00
parent d1aa966737
commit 826dde759f
2 changed files with 46 additions and 14 deletions

View File

@ -102,9 +102,9 @@ Proof.
auto.
+ (* A quote doesn't have a next step, and so is final. *)
apply chain_final. auto.
+ (* In compoition, by induction, we know that the two sub-expressions produce
+ (* In composition, by induction, we know that the two sub-expressions produce
proper evaluation chains. Chains can be composed (via eval_chain_merge). *)
eapply eval_chain_merge with vs2; auto.
eapply eval_chain_merge; eauto.
- intros i vs vs' Hsem.
(* The evaluation chain depends on the specific intrinsic in use. *)
inversion Hsem; subst;
@ -162,15 +162,15 @@ Proof.
- destruct i; ensure_valid_stack ();
(* Get rid of trivial cases that match one-to-one. *)
simpl in Hev; try (injection Hev as Hinj; subst; solve_basic ()).
+ (* compose with one quoted value *)
+ (* compose with one quoted value is not final, but an error. *)
destruct v. inversion Hev.
+ (* compose with two quoted values. *)
destruct v; destruct v0.
injection Hev as Hinj; subst; solve_basic ().
+ (* Apply is not final. *) destruct v. inversion Hev.
- (* Quote is always final, trivially. *)
- (* Quote is always final, trivially, and the semantics match easily. *)
simpl in Hev. injection Hev as Hinj; subst. solve_basic ().
- (* Compose is never final. *)
- (* Compose is never final, so we don't need to handle it here. *)
simpl in Hev. destruct (eval_step vs e1); inversion Hev.
Qed.
@ -181,23 +181,35 @@ Theorem eval_step_middle_sem : forall (e ei: expr) (vs vsi vs' : value_stack),
Proof.
intros e. induction e; intros ei vs vsi vs' Hev Hsem.
- destruct i; ensure_valid_stack ().
+ (* compose with one quoted value. *)
+ (* compose with one quoted value; invalid. *)
destruct v. inversion Hev.
+ (* compose with two quoted values. *)
+ (* compose with two quoted values; not a middle step. *)
destruct v; destruct v0. inversion Hev.
+ (* Apply *)
destruct v. injection Hev as Hinj; subst.
solve_basic (). auto.
- inversion Hev.
- (* quoting an expression is not middle. *)
inversion Hev.
- simpl in Hev.
destruct (eval_step vs e1) eqn:Hev1.
+ inversion Hev.
+ injection Hev as Hinj; subst. inversion Hsem; subst.
+ (* Step led to an error, which can't happen in a chain. *)
inversion Hev.
+ (* Left expression makes a non-final step. Milk this for equalities first. *)
injection Hev as Hinj; subst.
(* The rest of the program (e_comp e e2) evaluates using our semantics,
which means that both e and e2 evaluate using our semantics. *)
inversion Hsem; subst.
(* By induction, e1 evaluates using our semantics if e does, which we just confirmed. *)
specialize (IHe1 e vs vsi vs2 Hev1 H2).
eapply Sem_e_comp. apply IHe1. apply H4.
+ injection Hev as Hinj; subst.
(* The composition rule can now be applied. *)
eapply Sem_e_comp; eauto.
+ (* Left expression makes a final step. Milk this for equalities first. *)
injection Hev as Hinj; subst.
(* Using eval_step_final, we know that e1 evaluates to the intermediate
state given our semantics. *)
specialize (eval_step_final_sem e1 vs vsi Hev1) as Hsem1.
eapply Sem_e_comp. apply Hsem1. apply Hsem.
(* The composition rule can now be applied. *)
eapply Sem_e_comp; eauto.
Qed.
Theorem eval_step_sem_back : forall (e : expr) (vs vs' : value_stack),
@ -210,7 +222,7 @@ Proof.
Qed.
Corollary eval_step_no_sem : forall (e : expr) (vs vs' : value_stack),
~ (Sem_expr vs e vs') -> ~(eval_chain vs e vs').
~(Sem_expr vs e vs') -> ~(eval_chain vs e vs').
Proof.
intros e vs vs' Hnsem Hch.
specialize (eval_step_sem_back _ _ _ Hch). auto.
@ -221,3 +233,22 @@ Require Import ExtrHaskellBasic.
Extraction Language Haskell.
Set Extraction KeepSingleton.
Extraction "UccGen.hs" expr eval_step true false or.
Remark eval_swap_two_values : forall (vs vs' : value_stack),
eval_step vs (e_int swap) = final vs' -> exists v1 v2 vst, vs = v1 :: v2 :: vst /\ vs' = v2 :: v1 :: vst.
Proof.
intros vs vs' Hev.
(* Can't proceed until we know more about the stack. *)
destruct vs as [|v1 [|v2 vs]].
- (* Invalid case; empty stack. *) inversion Hev.
- (* Invalid case; stack only has one value. *) inversion Hev.
- (* Valid case: the stack has two values. *) injection Hev. eauto.
Qed.
Remark eval_swap_two_values' : forall (vs vs' : value_stack),
eval_step vs (e_int swap) = final vs' -> exists v1 v2 vst, vs = v1 :: v2 :: vst /\ vs' = v2 :: v1 :: vst.
Proof.
intros vs vs' Hev.
ensure_valid_stack ().
injection Hev. eauto.
Qed.

View File

@ -2,6 +2,7 @@
title: "Formalizing Dawn in Coq"
date: 2021-11-20T19:04:57-08:00
tags: ["Coq", "Dawn", "Programming Languages"]
description: "In this article, we use Coq to write down machine-checked semantics for the untyped concatenative calculus."
---
The [_Foundations of Dawn_](https://www.dawn-lang.org/posts/foundations-ucc/) article came up