Skip to content

Commit a214a56

Browse files
committed
opsem: generate spec lemmas
1 parent 5e383f5 commit a214a56

File tree

2 files changed

+128
-4
lines changed

2 files changed

+128
-4
lines changed

src/ecProcSem.ml

+40-2
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ let rec translate_i (env : senv) (cont : senv -> mode * expr) (i : instr) =
9090

9191
match mode with
9292
| `Det -> f_dmap tya tyb d body
93-
| `Distr -> f_dlet_simpl tya tyb d body
93+
| `Distr -> f_dlet_simpl tya (oget (as_tdistr tyb)) d body
9494

9595
in (`Distr, expr_of_form mhr aout)
9696
end
@@ -136,7 +136,45 @@ let rec translate_i (env : senv) (cont : senv -> mode * expr) (i : instr) =
136136

137137
let cmode, c = (cont env') in
138138

139-
(mode, e_let lv (e_if e bt bf) c) (* FIXME *)
139+
begin
140+
match mode, cmode with
141+
| `Det, _ ->
142+
(cmode, e_let lv (e_if e bt bf) c)
143+
144+
| `Distr, `Det ->
145+
let body = form_of_expr mhr (e_if e bt bf) in
146+
let tya = oget (as_tdistr body.f_ty) in
147+
let v = EcIdent.create "v" in
148+
let vx = f_local v tya in
149+
let aout =
150+
f_dmap
151+
tya
152+
c.e_ty
153+
body
154+
(f_lambda
155+
[v, GTty tya]
156+
(f_let lv vx (form_of_expr mhr c)))
157+
158+
in (`Distr, expr_of_form mhr aout)
159+
160+
| `Distr, `Distr ->
161+
let body = form_of_expr mhr (e_if e bt bf) in
162+
let tya = oget (as_tdistr body.f_ty) in
163+
let tyb = oget (as_tdistr c.e_ty) in
164+
let v = EcIdent.create "v" in
165+
let vx = f_local v tya in
166+
let aout =
167+
f_dlet_simpl
168+
tya
169+
tyb
170+
body
171+
(f_lambda
172+
[v, GTty tya]
173+
(f_let lv vx (form_of_expr mhr c)))
174+
175+
in (`Distr, expr_of_form mhr aout)
176+
177+
end
140178

141179
| Scall (Some lv, ({ x_top = { m_top = `Concrete (p, _) }; x_sub = f } as xp), args) ->
142180
let fd = oget (EcEnv.Fun.by_xpath_opt xp env.env) in

src/ecScope.ml

+88-2
Original file line numberDiff line numberDiff line change
@@ -1399,7 +1399,7 @@ module Op = struct
13991399
let cont (env : Sem.senv) =
14001400
(`Det, Sem.translate_e env ret) in
14011401

1402-
let _, aout = Sem.translate_s env cont body.f_body in
1402+
let mode, aout = Sem.translate_s env cont body.f_body in
14031403
let aout = form_of_expr mhr aout in (* FIXME: translate to forms directly? *)
14041404
let aout = f_lambda (List.map2 (fun (_, ty) x -> (x, GTty ty)) params ids) aout in
14051405

@@ -1413,7 +1413,93 @@ module Op = struct
14131413
op_unfold = None;
14141414
} in
14151415

1416-
bind scope (unloc op.ppo_name, opdecl)
1416+
let oppath = EcPath.pqname (path scope) (unloc op.ppo_name) in
1417+
1418+
let scope = bind scope (unloc op.ppo_name, opdecl) in
1419+
1420+
let scope =
1421+
let prax =
1422+
let locs = List.map (fun (x, ty) -> (EcIdent.create x, ty)) params in
1423+
let res = f_pvar pv_res sig_.fs_ret mhr in
1424+
let resx = EcIdent.create "v" in
1425+
let resv = f_local resx sig_.fs_ret in
1426+
let prmem = EcIdent.create "&m" in
1427+
1428+
let mu =
1429+
let sem =
1430+
f_app
1431+
(f_op oppath [] opdecl.op_ty)
1432+
(List.map (fun (x, ty) -> f_local x ty) locs)
1433+
(match mode with `Det -> sig_.fs_ret | `Distr -> tdistr sig_.fs_ret) in
1434+
1435+
match mode with
1436+
| `Det ->
1437+
f_if (f_eq sem resv) f_r1 f_r0
1438+
1439+
| `Distr ->
1440+
f_mu_x sem resv
1441+
in
1442+
1443+
f_forall
1444+
[(prmem, GTmem EcMemory.abstract_mt)]
1445+
(f_forall
1446+
(List.map (fun (x, ty) -> (x, GTty ty)) ((resx, sig_.fs_ret) :: locs))
1447+
(f_eq
1448+
(f_pr prmem
1449+
f
1450+
(f_tuple (List.map (fun (x, ty) -> f_local x ty) locs))
1451+
(f_eq res resv))
1452+
mu))
1453+
in
1454+
1455+
let prax = EcDecl.{
1456+
ax_tparams = [];
1457+
ax_spec = prax;
1458+
ax_kind = `Lemma;
1459+
ax_loca = op.ppo_locality;
1460+
ax_visibility = `Visible;
1461+
} in
1462+
1463+
Ax.bind scope (unloc op.ppo_name ^ "_opsem", prax) in
1464+
1465+
let scope =
1466+
match mode with
1467+
| `Det ->
1468+
let hax =
1469+
let locs = List.map (fun (x, ty) -> (EcIdent.create x, ty)) params in
1470+
let res = f_pvar pv_res sig_.fs_ret mhr in
1471+
let args = f_pvar pv_arg sig_.fs_arg mhr in
1472+
1473+
f_forall
1474+
(List.map (fun (x, ty) -> (x, GTty ty)) locs)
1475+
(f_hoareF
1476+
(f_eq
1477+
args
1478+
(f_tuple (List.map (fun (x, ty) -> f_local x ty) locs)))
1479+
f
1480+
(f_eq
1481+
res
1482+
(f_app
1483+
(f_op oppath [] opdecl.op_ty)
1484+
(List.map (fun (x, ty) -> f_local x ty) locs)
1485+
sig_.fs_ret)))
1486+
in
1487+
1488+
let prax = EcDecl.{
1489+
ax_tparams = [];
1490+
ax_spec = hax;
1491+
ax_kind = `Lemma;
1492+
ax_loca = op.ppo_locality;
1493+
ax_visibility = `Visible;
1494+
} in
1495+
1496+
Ax.bind scope (unloc op.ppo_name ^ "_opsem_det", prax)
1497+
1498+
| `Distr ->
1499+
scope
1500+
in
1501+
1502+
scope
14171503
end
14181504

14191505
(* -------------------------------------------------------------------- *)

0 commit comments

Comments
 (0)