first attempt
This commit is contained in:
parent
6c93d38e81
commit
61a7d2befb
4 changed files with 120 additions and 2 deletions
|
|
@ -1 +1,99 @@
|
||||||
def hello := "world"
|
import Batteries.Data.Rat.Basic
|
||||||
|
import Batteries.Control.Lawful.MonadLift
|
||||||
|
|
||||||
|
inductive Ast
|
||||||
|
| lit (n : Rat)
|
||||||
|
| add (l r : Ast)
|
||||||
|
| sub (l r : Ast)
|
||||||
|
| mul (l r : Ast)
|
||||||
|
| div (l r : Ast)
|
||||||
|
|
||||||
|
instance : Coe Rat Ast where coe := .lit
|
||||||
|
instance : OfScientific Ast where
|
||||||
|
ofScientific a b c := .lit (.ofScientific a b c)
|
||||||
|
instance : OfNat Ast n where ofNat := .lit n
|
||||||
|
|
||||||
|
instance : Add Ast where add := .add
|
||||||
|
instance : Sub Ast where sub := .sub
|
||||||
|
instance : Mul Ast where mul := .mul
|
||||||
|
instance : Div Ast where div := .div
|
||||||
|
|
||||||
|
def Ast.interpret : Ast → Rat
|
||||||
|
| lit n => n
|
||||||
|
| add l r => l.interpret + r.interpret
|
||||||
|
| sub l r => l.interpret - r.interpret
|
||||||
|
| mul l r => l.interpret * r.interpret
|
||||||
|
| div l r => l.interpret / r.interpret
|
||||||
|
|
||||||
|
#eval Ast.interpret <| 3/2 + 0.5
|
||||||
|
|
||||||
|
inductive Op
|
||||||
|
| push (n : Rat)
|
||||||
|
| add
|
||||||
|
| sub
|
||||||
|
| mul
|
||||||
|
| div
|
||||||
|
deriving Repr
|
||||||
|
|
||||||
|
-- TODO: prove that the stack manip is all good throughout
|
||||||
|
def Op.pop_push : Op → Nat × Nat
|
||||||
|
| push _ => (0, 1)
|
||||||
|
| _ => (2, 1)
|
||||||
|
|
||||||
|
abbrev Ops := Array Op
|
||||||
|
|
||||||
|
def pushM (x : α) : StateM (Array α) Unit :=
|
||||||
|
modify <| (·.push x)
|
||||||
|
|
||||||
|
def popM? : StateM (Array α) (Option α) := do
|
||||||
|
let top ← Array.back? <$> get
|
||||||
|
modify Array.pop
|
||||||
|
return top
|
||||||
|
|
||||||
|
abbrev M := OptionT (StateM (Array Rat))
|
||||||
|
instance : LawfulMonad M := sorry
|
||||||
|
|
||||||
|
def Op.action (op : Op) : M Unit := do
|
||||||
|
match op with
|
||||||
|
| .push n => pushM n
|
||||||
|
| .add => pushM <| (← popM?) + (← popM?)
|
||||||
|
| .sub => pushM <| (← popM?) - (← popM?)
|
||||||
|
| .mul => pushM <| (← popM?) * (← popM?)
|
||||||
|
| .div => pushM <| (← popM?) / (← popM?)
|
||||||
|
|
||||||
|
def Ops.action (ops : Ops) : M Unit := ops.forM Op.action
|
||||||
|
|
||||||
|
def Ops.run (ops : Ops) : Option Rat :=
|
||||||
|
(do
|
||||||
|
ops.action
|
||||||
|
popM?
|
||||||
|
).run #[] |>.fst
|
||||||
|
|
||||||
|
def Ast.compile : Ast → Ops
|
||||||
|
| .lit n => #[.push n]
|
||||||
|
| .add l r => l.compile ++ r.compile ++ #[.add]
|
||||||
|
| .sub l r => l.compile ++ r.compile ++ #[.sub]
|
||||||
|
| .mul l r => l.compile ++ r.compile ++ #[.mul]
|
||||||
|
-- Note that l and r are flipped here. compilation!
|
||||||
|
| .div l r => r.compile ++ l.compile ++ #[.div]
|
||||||
|
|
||||||
|
#eval (3/2 + 0.5 : Ast) |>.compile.run
|
||||||
|
|
||||||
|
@[simp]
|
||||||
|
theorem Ops.append_action (a b : Ops)
|
||||||
|
: (a ++ b).action = (do a.action; b.action) := by
|
||||||
|
rw [action]
|
||||||
|
exact Array.forM_append
|
||||||
|
|
||||||
|
@[simp]
|
||||||
|
theorem Ops.push_action (ops : Ops) (op : Op)
|
||||||
|
: action (ops.push op) = (do ops.action; op.action) := by
|
||||||
|
rw [Array.push_eq_append, append_action]
|
||||||
|
have : op.action = action #[op] := by simp [action]
|
||||||
|
rw [this]
|
||||||
|
|
||||||
|
theorem Ast.compile_sound (ast : Ast)
|
||||||
|
: ast.compile.run = some ast.interpret := by
|
||||||
|
induction ast
|
||||||
|
· rfl
|
||||||
|
simp [compile]
|
||||||
|
|
|
||||||
15
lake-manifest.json
Normal file
15
lake-manifest.json
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
{"version": "1.1.0",
|
||||||
|
"packagesDir": ".lake/packages",
|
||||||
|
"packages":
|
||||||
|
[{"url": "https://github.com/leanprover-community/batteries",
|
||||||
|
"type": "git",
|
||||||
|
"subDir": null,
|
||||||
|
"scope": "leanprover-community",
|
||||||
|
"rev": "f1a7afdb343196b33bf9137b232eb69446065925",
|
||||||
|
"name": "batteries",
|
||||||
|
"manifestFile": "lake-manifest.json",
|
||||||
|
"inputRev": "main",
|
||||||
|
"inherited": false,
|
||||||
|
"configFile": "lakefile.toml"}],
|
||||||
|
"name": "bytecode",
|
||||||
|
"lakeDir": ".lake"}
|
||||||
|
|
@ -8,3 +8,8 @@ name = "Bytecode"
|
||||||
[[lean_exe]]
|
[[lean_exe]]
|
||||||
name = "bytecode"
|
name = "bytecode"
|
||||||
root = "Main"
|
root = "Main"
|
||||||
|
|
||||||
|
[[require]]
|
||||||
|
name = "batteries"
|
||||||
|
scope = "leanprover-community"
|
||||||
|
rev = "main"
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
leanprover/lean4:v4.16.0-rc2
|
leanprover/lean4:v4.19.0-rc2
|
||||||
Loading…
Reference in a new issue