Skip to content

Commit cdcbf76

Browse files
committed
Support for mutable expr and for loop
1 parent 52eeab6 commit cdcbf76

2 files changed

Lines changed: 31 additions & 7 deletions

File tree

‎RandomDo/Tactic/Computable/Deriving.lean‎

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Authors: Gaëtan Serré
55
-/
66
module
77

8-
public import RandomDo.Tactic.Computable.Counterparts
8+
public meta import RandomDo.Tactic.Computable.Counterparts
99
public import RandomDo.Monad.MeasurableSpace
1010
public meta import Lean.Elab.Tactic.Basic
1111

@@ -23,16 +23,22 @@ noncomputable def shifted : Measure ℝ := rdo
2323
2424
adds `shiftedComputable : RandPCG IO Float`, which draws from `NumLean.normal' 0 1` and adds one.
2525
26-
The Giry monad and its two operations become `RandPCG IO`, `pure` and `bind`. Anything else is
27-
rebuilt from the counterpart `@[computable_as]` records for its head, with its arguments translated
28-
in turn and its instances synthesized anew. A term translates into a term of the translation of its
26+
The Giry monad and its two operations become `RandPCG IO`, `pure` and `bind`, the `for` loop of
27+
`rdo` becomes the `for` loop of that monad, and a `let` stays a `let`. Anything else is rebuilt
28+
from the counterpart `@[computable_as]` records for its head, with its arguments translated in turn
29+
and its instances synthesized anew. A term translates into a term of the translation of its
2930
type; where the rebuilt one does not, its head is a definition nothing is known about, and its body
3031
is read in its place. `@[computable]` records the program it writes, so a program drawing from
3132
another translates into one calling that other's translation.
3233
3334
Two things extend the attribute: an `@[computable_as]` entry, and an alternative of `translate` for
3435
a construct of `rdo` it has not been taught.
3536
37+
The counterparts are imported `meta` as well as publicly, and so reach every module the attribute
38+
does. A translated program is written to be run, and a `run_cmd` or an `#eval` runs it in the very
39+
module that writes it: the interpreter then asks for the code of what it calls, which a plain
40+
`import` does not carry.
41+
3642
`set_option trace.computable true` prints what each piece became.
3743
-/
3844

@@ -61,6 +67,9 @@ partial def translate (σ : FVarSubst) (e : Expr) : MetaM Expr :=
6167
| MeasurableSpaceBind.mBind _ _ _ _ _ _ p k =>
6268
mkAppOptM ``Bind.bind #[← computableMonad, none, none, none,
6369
← translate σ p, ← translate σ k]
70+
| MeasurableSpaceForIn.forIn _ _ _ _ _ _ xs init body =>
71+
mkAppOptM ``ForIn.forIn #[← computableMonad, none, none, none, none,
72+
← translate σ xs, ← translate σ init, ← translate σ body]
6473
| MeasureTheory.Measure α _ => return mkApp (← computableMonad) (← translate σ α)
6574
/- A subtype is its carrier, and one of its values is the value it carries: the constraint and
6675
the proof of it are what a computable counterpart does not have. -/
@@ -74,6 +83,9 @@ partial def translate (σ : FVarSubst) (e : Expr) : MetaM Expr :=
7483
let x := xs[0]!.fvarId!
7584
withLocalDeclD (← x.getUserName) (← translate σ (← x.getType)) fun y ↦ do
7685
mkLambdaFVars #[y] (← translate (σ.insert x y) body)
86+
| .letE n t v b _ => withLetDecl n t v fun x ↦ do
87+
withLetDecl n (← translate σ t) (← translate σ v) fun y ↦ do
88+
mkLetFVars #[y] (← translate (σ.insert x.fvarId! y) (b.instantiate1 x))
7789
| _ => translateApp σ e
7890

7991
/-- Rebuild an application from the counterpart of its head; where nothing known about that head

‎Test/Computable.lean‎

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ module
22

33
public import Test.IsMarkov
44
public import Test.Bind
5+
public meta import RandomDo
56
import Batteries.Data.Float.Basic
67

78
set_option linter.style.header false
@@ -10,7 +11,7 @@ set_option trace.computable true
1011

1112
namespace Test.Computable
1213

13-
open Test.IsMarkov NumLean Lean.Elab.Command
14+
open Test.IsMarkov NumLean Lean.Elab.Command MeasureTheory ProbabilityTheory
1415

1516
def logComputable {α : Type} [Lean.ToMessageData α] (prog : RandPCG IO α) : CommandElabM Unit := do
1617
let x ← (IO.runRandPCG prog : IO α)
@@ -24,9 +25,9 @@ run_cmd logComputable sumTwoComputable
2425

2526
@[computable]
2627
noncomputable
27-
def unfoldSumTwo : MeasureTheory.Measure ℝ := rdo
28+
def unfoldSumTwo : Measure ℝ := rdo
2829
let y ← sumTwo
29-
let x ← ProbabilityTheory.gaussianReal 0 1
30+
let x ← gaussianReal 0 1
3031
return x + y
3132

3233
attribute [computable] centred
@@ -47,4 +48,15 @@ attribute [computable] Bind.twoCoins
4748

4849
run_cmd logComputable (Bind.twoCoinsComputable)
4950

51+
@[computable]
52+
noncomputable
53+
def ex1 : Measure ℝ := rdo
54+
let mut x := 0
55+
for _ in List.range 1000 rdo
56+
let y ← gaussianReal 0 1
57+
x := x + y
58+
return x
59+
60+
run_cmd logComputable (ex1Computable)
61+
5062
end Test.Computable

0 commit comments

Comments
 (0)