Skip to content

Commit 2040979

Browse files
authored
Prove that well-formed Environment compiles to well-formed SymEnv (cedar-policy#661)
Signed-off-by: Zhengyao Lin <zyal@amazon.com>
1 parent 1a76346 commit 2040979

7 files changed

Lines changed: 1280 additions & 39 deletions

File tree

cedar-lean/Cedar/Thm/Data/List/Lemmas.lean

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,14 @@ theorem mapM₂_eq_mapM [Monad m] [LawfulMonad m] [SizeOf α] [SizeOf β]
383383
:= by
384384
simp only [mapM₂, attach₂, mapM_pmap_subtype]
385385

386+
theorem mapM₃_eq_mapM [Monad m] [LawfulMonad m] [SizeOf α] [SizeOf β]
387+
(f : (α × β) → m γ)
388+
(as : List (α × β)) :
389+
List.mapM₃ as (λ x : { x // sizeOf x.snd < 1 + (1 + sizeOf as) } => f x.val) =
390+
List.mapM f as
391+
:= by
392+
simp only [mapM₃, attach₃, mapM_pmap_subtype]
393+
386394
theorem mapM_implies_nil {f : α → Except β γ} {as : List α}
387395
(h₁ : List.mapM f as = Except.ok []) :
388396
as = []
@@ -1430,4 +1438,62 @@ theorem find?_compose {α β} (f : α → β) (p₁ : β → Bool) (p₂ : α
14301438
specialize hₐ head
14311439
simp only [Function.comp_apply, heq₁, heq₂, Bool.false_eq_true] at hₐ
14321440
case _ => exact h hₐ
1441+
1442+
theorem mem_implies_mem_eraseDups
1443+
[BEq α] [LawfulBEq α]
1444+
{xs : List α} {x : α}
1445+
(hmem : x ∈ xs) :
1446+
x ∈ xs.eraseDups
1447+
:= by
1448+
cases xs with
1449+
| nil => contradiction
1450+
| cons hd tl =>
1451+
simp only [List.eraseDups_cons, List.mem_cons]
1452+
simp only [List.mem_cons] at hmem
1453+
cases hx : x == hd
1454+
· simp only [beq_eq_false_iff_ne, ne_eq] at hx
1455+
apply Or.inr
1456+
simp only [hx, false_or] at hmem
1457+
apply mem_implies_mem_eraseDups
1458+
apply List.mem_filter.mpr
1459+
simp only [hmem, true_and]
1460+
simp only [Bool.not_eq_eq_eq_not, Bool.not_true, beq_eq_false_iff_ne, ne_eq]
1461+
exact hx
1462+
· apply Or.inl
1463+
simp only [beq_iff_eq] at hx
1464+
exact hx
1465+
termination_by xs.length
1466+
decreasing_by
1467+
calc
1468+
(List.filter (fun b => !b == hd) tl).length <= tl.length := by
1469+
apply List.length_filter_le
1470+
_ < xs.length := by
1471+
simp [*]
1472+
1473+
theorem mem_eraseDups_implies_mem
1474+
[BEq α] [LawfulBEq α]
1475+
{xs : List α} {x : α}
1476+
(hmem : x ∈ xs.eraseDups) :
1477+
x ∈ xs
1478+
:= by
1479+
cases xs with
1480+
| nil => contradiction
1481+
| cons hd tl =>
1482+
simp only [eraseDups_cons, mem_cons] at hmem
1483+
simp only [mem_cons]
1484+
cases hmem with
1485+
| inl h => exact Or.inl h
1486+
| inr h =>
1487+
apply Or.inr
1488+
have := mem_eraseDups_implies_mem h
1489+
have := List.mem_filter.mp this
1490+
exact this.1
1491+
termination_by xs.length
1492+
decreasing_by
1493+
calc
1494+
(List.filter (fun b => !b == hd) tl).length <= tl.length := by
1495+
apply List.length_filter_le
1496+
_ < xs.length := by
1497+
simp [*]
1498+
14331499
end List

cedar-lean/Cedar/Thm/Data/Map.lean

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,13 @@ theorem contains_iff_some_find? {α β} [BEq α] {m : Map α β} {k : α} :
201201
m.contains k ↔ ∃ v, m.find? k = .some v
202202
:= by simp [contains, Option.isSome_iff_exists]
203203

204+
theorem find?_some_implies_contains {α β} [BEq α] {m : Map α β} {k : α} {v : β} :
205+
m.find? k = .some v → m.contains k
206+
:= by
207+
intros h
208+
apply contains_iff_some_find?.mpr
209+
simp [h]
210+
204211
theorem not_contains_of_empty {α β} [BEq α] (k : α) :
205212
¬ (Map.empty : Map α β).contains k
206213
:= by simp [contains, empty, find?, List.find?]
@@ -427,7 +434,7 @@ theorem find?_implies_make_find?
427434
{l : List (α × β)}
428435
{k : α} {v : β}
429436
(h : List.find? (λ x => x.fst == k) l = some (k, v)) :
430-
(Data.Map.make l).find? k = some v
437+
(make l).find? k = some v
431438
:= by
432439
apply (in_list_iff_find?_some (Data.Map.make_wf l)).mp
433440
simp only [make, Data.Map.kvs]
@@ -1116,4 +1123,54 @@ theorem wellFormed_correct {α β} [LT α] [StrictLT α] [DecidableLT α] {m : M
11161123
apply wf_iff_sorted.mp
11171124
exact h
11181125

1126+
/--
1127+
If a key exists in `l₂` but not in `l₁`,
1128+
then `Map.make (l₁ ++ l₂)` contains that key.
1129+
-/
1130+
theorem map_make_append_find_disjoint
1131+
[LT α] [StrictLT α] [DecidableEq α] [DecidableLT α]
1132+
[SizeOf α] [SizeOf β]
1133+
{l₁ : List (α × β)} {l₂ : List (α × β)} {k : α}
1134+
(hfind₁ : l₁.find? (λ ⟨k', _⟩ => k' == k) = none)
1135+
(hfind₂ : (l₂.find? (λ ⟨k', _⟩ => k' == k)).isSome) :
1136+
∃ v,
1137+
(Map.make (l₁ ++ l₂)).find? k = some v ∧
1138+
(k, v) ∈ l₂
1139+
:= by
1140+
have hwf : (Map.make (l₁ ++ l₂)).WellFormed := by
1141+
exact Map.make_wf _
1142+
have hsub :
1143+
(Map.make (l₁ ++ l₂)).kvs ⊆ l₁ ++ l₂
1144+
:= by
1145+
apply List.canonicalize_subseteq
1146+
simp [Subset, List.Subset] at hsub
1147+
have ⟨v, hv⟩ :
1148+
∃ v, (Map.make (l₁ ++ l₂)).find? k = some v
1149+
:= by
1150+
simp only [Option.isSome] at hfind₂
1151+
split at hfind₂
1152+
rotate_left
1153+
contradiction
1154+
rename_i kv hkv
1155+
exists kv.snd
1156+
apply Map.find?_implies_make_find?
1157+
simp [List.find?_append]
1158+
apply Or.inr
1159+
constructor
1160+
· simp only [List.find?_eq_none, beq_iff_eq, Prod.forall] at hfind₁
1161+
exact hfind₁
1162+
have := List.find?_some hkv
1163+
simp only [beq_iff_eq] at this
1164+
simp only [hkv]
1165+
simp [←this]
1166+
simp only [hv, Option.some.injEq, exists_eq_left']
1167+
have := Map.find?_mem_toList hv
1168+
have := hsub k v this
1169+
cases this with
1170+
| inl hmem₁ =>
1171+
have := List.find?_eq_none.mp hfind₁
1172+
specialize this (k, v) hmem₁
1173+
simp at this
1174+
| inr h => exact h
1175+
11191176
end Cedar.Data.Map

cedar-lean/Cedar/Thm/SymCC/Compiler/WellTyped.lean

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,9 +1527,10 @@ theorem compile_well_typed_call
15271527
simp [hty_comp_x1, hty_comp_x2, hty_x1, hty_x2, TermType.ofType]
15281528

15291529
/--
1530-
Compiling a well-typed expression should produce a term of the corresponding `TermType`.
1530+
Compiling a well-typed expression should produce a term of the corresponding `TermType`,
1531+
assuming that the expression is well-formed in the symbolic environment.
15311532
-/
1532-
theorem compile_well_typed {Γ : Environment} {εnv : SymEnv} {tx : TypedExpr} :
1533+
theorem compile_well_typed_on_wf_expr {Γ : Environment} {εnv : SymEnv} {tx : TypedExpr} :
15331534
CompileWellTypedCondition tx Γ εnv →
15341535
CompileWellTyped tx εnv
15351536
:= by
@@ -1541,52 +1542,52 @@ theorem compile_well_typed {Γ : Environment} {εnv : SymEnv} {tx : TypedExpr} :
15411542
have ⟨h1, h2, h3⟩ := h.eliminate_ite
15421543
apply compile_well_typed_ite
15431544
any_goals apply CompileWellTyped.add_wf
1544-
any_goals apply compile_well_typed
1545+
any_goals apply compile_well_typed_on_wf_expr
15451546
any_goals assumption
15461547
case and =>
15471548
have ⟨ha, hb⟩ := h.eliminate_or_and ?_
15481549
apply (compile_well_typed_or_and ?_ ?_).right
15491550
any_goals apply CompileWellTyped.add_wf
1550-
any_goals apply compile_well_typed
1551+
any_goals apply compile_well_typed_on_wf_expr
15511552
any_goals assumption
15521553
any_goals simp
15531554
case or =>
15541555
have ⟨ha, hb⟩ := h.eliminate_or_and ?_
15551556
apply (compile_well_typed_or_and ?_ ?_).left
15561557
any_goals apply CompileWellTyped.add_wf
1557-
any_goals apply compile_well_typed
1558+
any_goals apply compile_well_typed_on_wf_expr
15581559
any_goals assumption
15591560
any_goals simp
15601561
case unaryApp =>
15611562
have hcond := h.eliminate_unaryApp
15621563
apply compile_well_typed_unaryApp
15631564
any_goals apply CompileWellTyped.add_wf
1564-
any_goals apply compile_well_typed
1565+
any_goals apply compile_well_typed_on_wf_expr
15651566
all_goals assumption
15661567
case binaryApp =>
15671568
have ⟨ha, hb⟩ := h.eliminate_binaryApp
15681569
apply compile_well_typed_binaryApp
15691570
any_goals apply CompileWellTyped.add_wf
1570-
any_goals apply compile_well_typed
1571+
any_goals apply compile_well_typed_on_wf_expr
15711572
any_goals assumption
15721573
case getAttr =>
15731574
have hcond := h.eliminate_getAttr
15741575
apply compile_well_typed_getAttr
15751576
any_goals apply CompileWellTyped.add_wf
1576-
any_goals apply compile_well_typed
1577+
any_goals apply compile_well_typed_on_wf_expr
15771578
all_goals assumption
15781579
case hasAttr =>
15791580
have hcond := h.eliminate_hasAttr
15801581
apply compile_well_typed_hasAttr
15811582
any_goals apply CompileWellTyped.add_wf
1582-
any_goals apply compile_well_typed
1583+
any_goals apply compile_well_typed_on_wf_expr
15831584
all_goals assumption
15841585
case set =>
15851586
have hcond := h.eliminate_set
15861587
apply compile_well_typed_set
15871588
· intros x hx
15881589
apply CompileWellTyped.add_wf
1589-
apply compile_well_typed (hcond x hx)
1590+
apply compile_well_typed_on_wf_expr (hcond x hx)
15901591
apply hcond
15911592
assumption
15921593
assumption
@@ -1595,7 +1596,7 @@ theorem compile_well_typed {Γ : Environment} {εnv : SymEnv} {tx : TypedExpr} :
15951596
apply compile_well_typed_record
15961597
· intros a x hx
15971598
apply CompileWellTyped.add_wf
1598-
apply compile_well_typed (hcond a x hx)
1599+
apply compile_well_typed_on_wf_expr (hcond a x hx)
15991600
apply hcond
16001601
assumption
16011602
assumption
@@ -1604,7 +1605,7 @@ theorem compile_well_typed {Γ : Environment} {εnv : SymEnv} {tx : TypedExpr} :
16041605
apply compile_well_typed_call
16051606
· intros x hx
16061607
apply CompileWellTyped.add_wf
1607-
apply compile_well_typed (hcond x hx)
1608+
apply compile_well_typed_on_wf_expr (hcond x hx)
16081609
apply hcond
16091610
assumption
16101611
assumption

0 commit comments

Comments
 (0)