-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
132 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,40 +1,45 @@ | ||
|
||
import Lean.Data.AssocList | ||
|
||
namespace Juvix.Core.Main | ||
|
||
open Lean | ||
|
||
abbrev Name : Type := String | ||
|
||
inductive Constant : Type where | ||
| int : Int → Constant | ||
| string : String → Constant | ||
deriving Inhabited, DecidableEq | ||
|
||
inductive BuiltinOp : Type where | ||
| add_int : BuiltinOp | ||
| sub_int : BuiltinOp | ||
| mul_int : BuiltinOp | ||
| div_int : BuiltinOp | ||
deriving Inhabited, DecidableEq | ||
|
||
mutual | ||
inductive Expr : Type where | ||
| var : Nat → Expr | ||
| ident : Name → Expr | ||
| const : Constant → Expr | ||
| app : Expr → Expr → Expr | ||
| builtin_app : (oper : BuiltinOp) → (args : List Expr) → Expr | ||
| constr_app : (constr : Name) → (args : List Expr) → Expr | ||
| lambda : (body : Expr) → Expr | ||
| let : (value : Expr) → (body : Expr) → Expr | ||
| case : (value : Expr) → (branches : List CaseBranch) → Expr | ||
| unit : Expr | ||
deriving Inhabited | ||
|
||
structure CaseBranch where | ||
constr : Name | ||
body : Expr | ||
end | ||
deriving Inhabited, BEq, DecidableEq | ||
|
||
inductive BinaryOp : Type where | ||
| add_int : BinaryOp | ||
| sub_int : BinaryOp | ||
| mul_int : BinaryOp | ||
| div_int : BinaryOp | ||
deriving Inhabited, BEq, DecidableEq | ||
|
||
inductive Expr : Type where | ||
| var : Nat → Expr | ||
| ident : Name → Expr | ||
| constr : Name → Expr | ||
| const : Constant → Expr | ||
| app : Expr → Expr → Expr | ||
| constr_app : Expr → Expr → Expr | ||
| binop : (oper : BinaryOp) → (arg₁ arg₂ : Expr) → Expr | ||
| lambda : (body : Expr) → Expr | ||
| save : (value : Expr) → (body : Expr) → Expr | ||
| branch : (constr : Name) → (body : Expr) → (next : Expr) → Expr | ||
| default : (body : Expr) → Expr | ||
| unit : Expr | ||
deriving Inhabited, BEq, DecidableEq | ||
|
||
structure Program where | ||
defs : List Expr | ||
defs : AssocList Name Expr | ||
main : Expr | ||
|
||
def Expr.mk_app (f : Expr) : List Expr → Expr | ||
| [] => f | ||
| x :: xs => Expr.mk_app (Expr.app f x) xs | ||
|
||
end Juvix.Core.Main |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,105 @@ | ||
|
||
import Juvix.Core.Main.Language | ||
import Mathlib.Tactic.CC | ||
|
||
namespace Juvix.Core.Main | ||
|
||
def f : Expr -> Expr := λ e => | ||
match e with | ||
| Expr.lambda (body := e) => e | ||
| _ => Expr.lambda (body := e) | ||
def eval_binop_int (op : BinaryOp) (i₁ i₂ : Int) : Int := | ||
match op with | ||
| BinaryOp.add_int => i₁ + i₂ | ||
| BinaryOp.sub_int => i₁ - i₂ | ||
| BinaryOp.mul_int => i₁ * i₂ | ||
| BinaryOp.div_int => i₁ / i₂ | ||
|
||
inductive Eval (P : Program) : Context → Expr → Value → Prop where | ||
| eval_var {ctx idx val} : | ||
ctx.get? idx = some val → | ||
Eval P ctx (Expr.var idx) val | ||
| eval_ident {ctx name expr val} : | ||
P.defs.find? name = some expr → | ||
Eval P [] expr val → | ||
Eval P ctx (Expr.ident name) val | ||
| eval_const {ctx c} : | ||
Eval P ctx (Expr.const c) (Value.const c) | ||
| eval_app {ctx ctx' f body arg val val'} : | ||
Eval P ctx f (Value.closure ctx' body) → | ||
Eval P ctx arg val → | ||
Eval P (val :: ctx') body val' → | ||
Eval P ctx (Expr.app f arg) val' | ||
| eval_constr_app {ctx ctr ctr_name ctr_args_rev arg val} : | ||
Eval P ctx ctr (Value.constr_app ctr_name ctr_args_rev) → | ||
Eval P ctx arg val → | ||
Eval P ctx (Expr.constr_app ctr arg) (Value.constr_app ctr_name (val :: ctr_args_rev)) | ||
| eval_binop {ctx op arg₁ arg₂ val₁ val₂} : | ||
Eval P ctx arg₁ (Value.const (Constant.int val₁)) → | ||
Eval P ctx arg₂ (Value.const (Constant.int val₂)) → | ||
Eval P ctx (Expr.binop op arg₁ arg₂) (Value.const (Constant.int (eval_binop_int op val₁ val₂))) | ||
| eval_lambda {ctx body} : | ||
Eval P ctx (Expr.lambda body) (Value.closure ctx body) | ||
| eval_save {ctx value body val val'} : | ||
Eval P ctx value val → | ||
Eval P (val :: ctx) body val' → | ||
Eval P ctx (Expr.save value body) val' | ||
| eval_branch_matches {ctx name args_rev body val} : | ||
Eval P (args_rev ++ ctx) body val → | ||
Eval P (Value.constr_app name args_rev :: ctx) (Expr.branch name body _) val | ||
| eval_branch_fails {ctx name name' next val} : | ||
name ≠ name' → | ||
Eval P ctx next val → | ||
Eval P (Value.constr_app name _ :: ctx) (Expr.branch name' _ next) val | ||
| eval_default {ctx body val} : | ||
Eval P ctx body val → | ||
Eval P (_ :: ctx) (Expr.default body) val | ||
| eval_unit {ctx} : | ||
Eval P ctx Expr.unit Value.unit | ||
|
||
theorem Eval.deterministic {P ctx e v₁ v₂} (h₁ : Eval P ctx e v₁) (h₂ : Eval P ctx e v₂) : v₁ = v₂ := by | ||
induction h₁ generalizing v₂ with | ||
| eval_var => | ||
cases h₂ <;> cc | ||
| eval_ident _ _ ih => | ||
specialize (@ih v₂) | ||
cases h₂ <;> cc | ||
| eval_const => | ||
cases h₂ <;> cc | ||
| eval_app _ _ _ ih ih' aih => | ||
cases h₂ with | ||
| eval_app hval harg => | ||
apply aih | ||
specialize (ih hval) | ||
specialize (ih' harg) | ||
simp_all | ||
| eval_constr_app _ _ ih ih' => | ||
cases h₂ with | ||
| eval_constr_app hctr harg => | ||
specialize (ih hctr) | ||
specialize (ih' harg) | ||
simp_all | ||
| eval_binop _ _ ih₁ ih₂ => | ||
cases h₂ with | ||
| eval_binop h₁ h₂ => | ||
specialize (ih₁ h₁) | ||
specialize (ih₂ h₂) | ||
simp_all | ||
| eval_lambda => | ||
cases h₂ <;> cc | ||
| eval_save _ _ ih ih' => | ||
cases h₂ with | ||
| eval_save hval hbody => | ||
specialize (ih hval) | ||
rw [<- ih] at hbody | ||
specialize (ih' hbody) | ||
simp_all | ||
| eval_branch_matches _ ih => | ||
specialize (@ih v₂) | ||
cases h₂ <;> cc | ||
| eval_branch_fails _ _ ih => | ||
specialize (@ih v₂) | ||
cases h₂ <;> cc | ||
| eval_default _ ih => | ||
specialize (@ih v₂) | ||
cases h₂ <;> cc | ||
| eval_unit => | ||
cases h₂ <;> cc | ||
|
||
end Juvix.Core.Main |