Skip to content
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
136 commits
Select commit Hold shift + click to select a range
61a1442
Initial level impl
john-h-kastner-aws Jan 8, 2025
ded0e6f
proof for `if` at level `0`
john-h-kastner-aws Jan 13, 2025
c7ad783
iwp
john-h-kastner-aws Jan 14, 2025
937fc95
tweak ite
john-h-kastner-aws Jan 22, 2025
4206195
reorg
john-h-kastner-aws Jan 22, 2025
cd611a0
wip
john-h-kastner-aws Jan 22, 2025
a94d440
wip
john-h-kastner-aws Feb 4, 2025
ba9a17c
wip
john-h-kastner-aws Feb 5, 2025
e66599b
reorg files
john-h-kastner-aws Feb 5, 2025
d5261cc
tidy
john-h-kastner-aws Feb 5, 2025
ea104a4
hasattr
john-h-kastner-aws Feb 5, 2025
0b64945
work on reachable_attr_step
john-h-kastner-aws Feb 5, 2025
f18e418
comments
john-h-kastner-aws Feb 5, 2025
ae34a26
introduce lemma to clean up proof
john-h-kastner-aws Feb 6, 2025
383e6ba
more cases
john-h-kastner-aws Feb 7, 2025
a56607b
tidy
john-h-kastner-aws Feb 7, 2025
2c3c037
tidy
john-h-kastner-aws Feb 7, 2025
f2158f8
reorg
john-h-kastner-aws Feb 7, 2025
7c52720
use match instead of if
john-h-kastner-aws Feb 10, 2025
8970e0d
tidy: use `symm` a less
john-h-kastner-aws Feb 10, 2025
e4a5402
dont need that lemma anymore
john-h-kastner-aws Feb 10, 2025
6b780af
tidy
john-h-kastner-aws Feb 10, 2025
f5b05c5
work on not_entities_then_not_slice
john-h-kastner-aws Feb 10, 2025
fac2ad4
slightly simplify `lit` case
john-h-kastner-aws Feb 11, 2025
6670bd1
simplify var cae a little
john-h-kastner-aws Feb 11, 2025
2232933
move lit inversion into litvar.lean
john-h-kastner-aws Feb 11, 2025
44ff0df
unary app sound
john-h-kastner-aws Feb 11, 2025
3633668
split checkLevel and checkRoot
john-h-kastner-aws Feb 11, 2025
4b2413a
dead code
john-h-kastner-aws Feb 11, 2025
f195a31
rename checkRoot to notEntityLit and adjust lit to accept non-entity
john-h-kastner-aws Feb 12, 2025
27600a4
add most of an inductive definition for level checking
john-h-kastner-aws Feb 14, 2025
f1eb7ba
prototype better record handling
john-h-kastner-aws Feb 14, 2025
202a805
rename to `List.unionAll` to match emina's code
john-h-kastner-aws Feb 14, 2025
4904872
nicer termination
john-h-kastner-aws Feb 14, 2025
130813a
fix up proofs
john-h-kastner-aws Feb 14, 2025
1686f02
fill hole in termination proof
john-h-kastner-aws Feb 17, 2025
596bfe1
fill in record case for not_entity_lit_spec
john-h-kastner-aws Feb 17, 2025
758be7d
finish check_level_checked_succ using inductive def
john-h-kastner-aws Feb 17, 2025
49ef4b2
tweak
john-h-kastner-aws Feb 17, 2025
ce786bd
Show termination for record in checked_eval_entity_reachable
john-h-kastner-aws Feb 17, 2025
ba92360
fill in record details
john-h-kastner-aws Feb 18, 2025
54540ae
nicer match syntax
john-h-kastner-aws Feb 18, 2025
e5fb2cd
stronger record inversion lemma
john-h-kastner-aws Feb 19, 2025
83e7891
another record inversion lemma
john-h-kastner-aws Feb 19, 2025
a9d158f
fill in more record details
john-h-kastner-aws Feb 19, 2025
4f22ed2
finish proof for equiv of inductive defs
john-h-kastner-aws Feb 19, 2025
234a2d4
notes
john-h-kastner-aws Feb 19, 2025
5fb9211
incorperate emina proof
john-h-kastner-aws Feb 20, 2025
cfcee35
split checked_eval_entity_reachable
john-h-kastner-aws Feb 20, 2025
d116e43
move lemma
john-h-kastner-aws Feb 20, 2025
f388aac
dont need that anymore
john-h-kastner-aws Feb 20, 2025
ca78ccb
fill in lemmas
john-h-kastner-aws Feb 20, 2025
8a872f6
rename_inductive
john-h-kastner-aws Feb 20, 2025
af8e3ab
simp onlys
john-h-kastner-aws Feb 20, 2025
8044bef
Merge remote-tracking branch 'origin/main' into levels-checking
john-h-kastner-aws Feb 21, 2025
7b732d8
tidy
john-h-kastner-aws Feb 21, 2025
1ce31eb
qualify names
john-h-kastner-aws Feb 21, 2025
8ceece6
use mapUnion
john-h-kastner-aws Feb 21, 2025
afdc460
proof for `.and` and `.or`
john-h-kastner-aws Feb 21, 2025
873a178
simplify proof for `or`
john-h-kastner-aws Feb 21, 2025
6ad7e5b
tweak and case
john-h-kastner-aws Feb 24, 2025
d25c46f
use inductive in more proofs
john-h-kastner-aws Feb 24, 2025
42e8782
split binaryapp soundness
john-h-kastner-aws Feb 24, 2025
488b794
proof for non-derefencing binary ops
john-h-kastner-aws Feb 24, 2025
bfa0881
Proof for `getTag` `hasTag` and `mem`
john-h-kastner-aws Feb 24, 2025
95eb346
proof for records
john-h-kastner-aws Feb 25, 2025
0634696
Merge remote-tracking branch 'origin/main' into levels-checking
john-h-kastner-aws Feb 25, 2025
6b13227
higher level thm
john-h-kastner-aws Feb 25, 2025
0c5f025
note
john-h-kastner-aws Feb 25, 2025
5ca2602
track max level for more precise checking on guard expr
john-h-kastner-aws Feb 28, 2025
4afc20b
soundness for sets
john-h-kastner-aws Feb 28, 2025
0749462
most of call
john-h-kastner-aws Feb 28, 2025
6152cd8
fix
john-h-kastner-aws Feb 28, 2025
2400296
use list lemma
john-h-kastner-aws Feb 28, 2025
1469d31
Merge remote-tracking branch 'origin/main' into levels-checking
john-h-kastner-aws Mar 3, 2025
3db7887
fixup binary opp
john-h-kastner-aws Mar 3, 2025
d38892a
Split `Slice.lean` to improve lean plugin latency
john-h-kastner-aws Mar 3, 2025
72a20bb
simp onlys
john-h-kastner-aws Mar 3, 2025
f0fccff
work on lemma
john-h-kastner-aws Mar 3, 2025
ffaca53
cleanup record case
john-h-kastner-aws Mar 4, 2025
e6eef51
finish call inversion lemma
john-h-kastner-aws Mar 4, 2025
8484ee5
Fix call soundness case for new updated inversion lemma
john-h-kastner-aws Mar 4, 2025
d5ee9f5
Fill in a map lemma
john-h-kastner-aws Mar 4, 2025
33f0f6f
work on data structure lemma
john-h-kastner-aws Mar 4, 2025
d3c5758
fill in data structure lemma
john-h-kastner-aws Mar 5, 2025
1cbb6c9
last datastructure lemma
john-h-kastner-aws Mar 5, 2025
952e938
Split relations for level checking arbitrary expr from entity access
john-h-kastner-aws Mar 5, 2025
63e4c03
EntityAccessAtLevel
john-h-kastner-aws Mar 6, 2025
b06a6a3
Update functional impl
john-h-kastner-aws Mar 6, 2025
05784b1
tweak
john-h-kastner-aws Mar 6, 2025
5e64bec
Extend typechecker inversion lemma for type annotation
john-h-kastner-aws Mar 6, 2025
25bbc7d
Merge remote-tracking branch 'origin/main' into levels-checking
john-h-kastner-aws Mar 6, 2025
391dce1
fix
john-h-kastner-aws Mar 6, 2025
5052af2
Merge branch 'type-annot-inversion' into levels-checking
john-h-kastner-aws Mar 6, 2025
f040b7c
tidy
john-h-kastner-aws Mar 6, 2025
29dcabb
remove
john-h-kastner-aws Mar 6, 2025
729b950
tidy
john-h-kastner-aws Mar 6, 2025
e739912
Add model for level checking and slicing
john-h-kastner-aws Mar 6, 2025
faeab8b
add tests and comments
john-h-kastner-aws Mar 7, 2025
4191cc2
tweak
john-h-kastner-aws Mar 7, 2025
9ea61fd
note about entity lits
john-h-kastner-aws Mar 7, 2025
3283207
fix
john-h-kastner-aws Mar 7, 2025
4ce0b79
Add inductive relation for level checking
john-h-kastner-aws Mar 7, 2025
26168ef
Merge branch 'level-slicing-model' into levels-checking
john-h-kastner-aws Mar 7, 2025
3ea3d20
fix
john-h-kastner-aws Mar 7, 2025
43c1e58
Merge remote-tracking branch 'origin/main' into levels-checking
john-h-kastner-aws Mar 10, 2025
5e63c7c
Allow access to literals that equal to current environement actoin
john-h-kastner-aws Mar 10, 2025
9635c59
Merge remote-tracking branch 'origin/main' into type-annot-inversion
john-h-kastner-aws Mar 10, 2025
dd8cd30
Merge branch 'type-annot-inversion' into levels-checking
john-h-kastner-aws Mar 10, 2025
4fce801
Allow access to literals that equal to current environement actoin
john-h-kastner-aws Mar 10, 2025
810539c
fix test function call and add more tests
john-h-kastner-aws Mar 10, 2025
a22f7ea
Merge remote-tracking branch 'origin/main' into fix-action-var-access
john-h-kastner-aws Mar 11, 2025
988a98c
Use method style calls
john-h-kastner-aws Mar 11, 2025
682721d
fix
john-h-kastner-aws Mar 11, 2025
9609bb9
Merge remote-tracking branch 'origin/main' into levels-checking
john-h-kastner-aws Mar 11, 2025
d3eea56
Merge branch 'fix-action-var-access' into levels-checking
john-h-kastner-aws Mar 11, 2025
207b2e2
theorem for isAuthorized
john-h-kastner-aws Mar 11, 2025
3a16d3e
Merge remote-tracking branch 'origin/main' into type-annot-inversion
john-h-kastner-aws Mar 12, 2025
28319ca
Merge branch 'type-annot-inversion' into levels-checking
john-h-kastner-aws Mar 12, 2025
3f52794
tweak
john-h-kastner-aws Mar 12, 2025
ce11d25
tweak
john-h-kastner-aws Mar 12, 2025
85ba37e
tweak
john-h-kastner-aws Mar 12, 2025
e4e4d16
tweak
john-h-kastner-aws Mar 12, 2025
9b2f82a
Merge remote-tracking branch 'origin/main' into type-annot-inversion
john-h-kastner-aws Mar 26, 2025
a4a4d69
Merge branch 'type-annot-inversion' into levels-checking
john-h-kastner-aws Mar 26, 2025
fb802dc
Merge remote-tracking branch 'origin/main' into type-annot-inversion
john-h-kastner-aws Mar 26, 2025
fb29c03
Merge branch 'type-annot-inversion' into levels-checking
john-h-kastner-aws Mar 26, 2025
7da2428
cleanup ite case
john-h-kastner-aws Mar 26, 2025
f4bb08b
tidy getAttr and hasAttr for records
john-h-kastner-aws Mar 27, 2025
b7c1a7f
tidy
john-h-kastner-aws Mar 27, 2025
af9b54b
record
john-h-kastner-aws Mar 28, 2025
36a7a1a
`suffices` for nicer proofs
john-h-kastner-aws Apr 1, 2025
9fd14e7
tidy if case
john-h-kastner-aws Apr 3, 2025
ecf8429
Merge remote-tracking branch 'origin' into levels-checking
john-h-kastner-aws Apr 8, 2025
825e01e
Merge remote-tracking branch 'origin/main' into levels-checking
john-h-kastner-aws Apr 8, 2025
f21bba6
Move more lemmas into data module
john-h-kastner-aws Apr 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cedar-lean/Cedar/Spec.lean
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import Cedar.Spec.Ext
import Cedar.Spec.Policy
import Cedar.Spec.Request
import Cedar.Spec.Response
import Cedar.Spec.Slice
import Cedar.Spec.Template
import Cedar.Spec.Value
import Cedar.Spec.Wildcard
67 changes: 67 additions & 0 deletions cedar-lean/Cedar/Spec/Slice.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/-
Copyright Cedar Contributors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-/

import Cedar.Spec.Value
import Cedar.Spec.Entities
import Cedar.Spec.Request
import Cedar.Data.SizeOf

/-!
This file defines entity slicing at a level
-/

namespace Cedar.Spec

open Cedar.Data

def flatten_union {α} [LT α] [DecidableLT α] : List (Set α) → Set α :=
List.foldl (· ∪ ·) ∅

def Value.sliceEUIDs (v : Value) : Set EntityUID :=
match v with
| .prim (.entityUID uid) => Set.singleton uid
-- TODO: You can't access these except by `in`, so maybe this could just be `Set.empty`
| .set s => flatten_union $ s.elts.attach.map λ e => e.val.sliceEUIDs
| .record r => flatten_union $ r.toList.attach.map λ e => e.val.snd.sliceEUIDs
| .prim _ | .ext _ => ∅
decreasing_by
· simp [←Nat.succ_eq_one_add, Nat.lt.step, Set.sizeOf_lt_of_mem e.property]
· simp only [Map.toList] at e
have _ := Map.sizeOf_lt_of_kvs r
have _ := List.sizeOf_lt_of_mem e.property
have _ : sizeOf e.val.snd < sizeOf e.val := by simp [sizeOf, Prod._sizeOf_1, Nat.one_add]
rw [record.sizeOf_spec] ; omega

def EntityData.sliceEUIDs (ed : EntityData) : Set EntityUID :=
(flatten_union $ ed.attrs.values.map Value.sliceEUIDs) ∪
(flatten_union $ ed.tags.values.map Value.sliceEUIDs)

def Request.sliceEUIDs (r : Request) : Set EntityUID :=
Set.make [r.principal, r.action, r.resource] ∪
(Value.record r.context).sliceEUIDs

def Entities.sliceAtLevel (es : Entities) (r : Request) (level : Nat) : Option Entities := do
let slice ← sliceAtLevel r.sliceEUIDs level
let slice ← slice.elts.mapM λ e => do some (e, ←(es.find? e))
some (Map.make slice)
where
sliceAtLevel (work : Set EntityUID) (level : Nat) : Option (Set EntityUID) :=
match level with
| 0 => some ∅
| Nat.succ level => do
let eds ← work.elts.mapM es.find?
let slice ← flatten_union <$> eds.mapM (λ ed => sliceAtLevel ed.sliceEUIDs level)
some (work ∪ slice)
1 change: 1 addition & 0 deletions cedar-lean/Cedar/Thm/Validation.lean
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import Cedar.Spec
import Cedar.Data
import Cedar.Validation
import Cedar.Thm.Validation.Levels
import Cedar.Thm.Validation.Validator
import Cedar.Thm.Validation.RequestEntityValidation

Expand Down
62 changes: 62 additions & 0 deletions cedar-lean/Cedar/Thm/Validation/Levels.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/-
Copyright Cedar Contributors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-/

import Cedar.Spec
import Cedar.Data
import Cedar.Validation
import Cedar.Thm.Validation.Typechecker
import Cedar.Thm.Validation.Typechecker.Types

import Cedar.Thm.Validation.Levels.CheckLevel
import Cedar.Thm.Validation.Levels.IfThenElse
import Cedar.Thm.Validation.Levels.GetAttr
import Cedar.Thm.Validation.Levels.HasAttr

namespace Cedar.Thm

open Cedar.Data
open Cedar.Spec
open Cedar.Validation

theorem level_based_slicing_is_sound {e : Expr} {tx : TypedExpr} {n : Nat} {c c₁ : Capabilities} {env : Environment} {request : Request} {slice entities : Entities}
(hs : slice = entities.sliceAtLevel request n)
(hc : CapabilitiesInvariant c request entities)
(hr : RequestAndEntitiesMatchEnvironment env request entities)
(ht : typeOf e c env = Except.ok (tx, c₁))
(hl : (checkLevel tx n).checked) :
evaluate e request entities = evaluate e request slice
:= by
cases e
case lit => simp [evaluate]
case var v => cases v <;> simp [evaluate]
case ite c t e =>
have ihc := @level_based_slicing_is_sound c
have iht := @level_based_slicing_is_sound t
have ihe := @level_based_slicing_is_sound e
exact level_based_slicing_is_sound_if hs hc hr ht hl ihc iht ihe
case and => sorry -- inductive case, similar ast rewriting concerns as `if`, type annotation could be buggy
case or => sorry -- inductive case, similar ast rewriting concerns as `if`, type annotation could be buggy
case unaryApp => sorry -- trivial inductive cases
case binaryApp => sorry -- includes tags cases which should follow the attr cases and `in` case which might be tricky
case getAttr e _ =>
have ihe := @level_based_slicing_is_sound e
exact level_based_slicing_is_sound_get_attr hs hc hr ht hl ihe
case hasAttr e _ =>
have ihe := @level_based_slicing_is_sound e
exact level_based_slicing_is_sound_has_attr hs hc hr ht hl ihe
case set => sorry -- trivial recursive case maybe a little tricky
case record => sorry -- likely to be tricky. Record cases are always hard, and here there might be an odd interaction with attribute access
case call => sorry -- should be the same as set
34 changes: 34 additions & 0 deletions cedar-lean/Cedar/Thm/Validation/Levels/Basic.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/-
Copyright Cedar Contributors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-/

import Cedar.Thm.Validation.Typechecker.Basic

namespace Cedar.Thm

/-!
Basic definitions for levels proof
-/

open Cedar.Spec
open Cedar.Validation

def TypedAtLevelIsSound (e : Expr) : Prop := ∀ {n : Nat} {tx : TypedExpr} {c c₁ : Capabilities} {env :Environment} {request : Request} {entities slice : Entities},
slice = entities.sliceAtLevel request n →
CapabilitiesInvariant c request entities →
RequestAndEntitiesMatchEnvironment env request entities →
typeOf e c env = Except.ok (tx, c₁) →
(checkLevel tx n).checked →
evaluate e request entities = evaluate e request slice
86 changes: 86 additions & 0 deletions cedar-lean/Cedar/Thm/Validation/Levels/CheckLevel.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/-
Copyright Cedar Contributors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-/

import Cedar.Validation

namespace Cedar.Thm

/-!
This file contains some simple lemmas about the `checkLevel` and `typedAtLevel`
functions that do not need reason about the slicing functions.
-/

open Cedar.Validation

theorem check_level_lit_inversion {p : Spec.Prim} {ty : CedarType} {n : Nat}
: (checkLevel (.lit p ty) n) = LevelCheckResult.mk true false
:= by simp [checkLevel]

theorem check_level_root_invariant (n n' : Nat) (e : TypedExpr)
: (checkLevel e n).root = (checkLevel e n').root
:= by
unfold checkLevel
cases e <;> simp
case ite | unaryApp =>
simp [check_level_root_invariant n n']
case binaryApp op _ _ _ =>
cases op
case mem | getTag | hasTag =>
simp [check_level_root_invariant (n - 1) (n' - 1)]
all_goals { simp [check_level_root_invariant n n'] }
case getAttr e _ _ | hasAttr e _ _ =>
cases e.typeOf
case entity =>
simp [check_level_root_invariant (n - 1) (n' - 1)]
all_goals { simp [check_level_root_invariant n n'] }
-- Hopefully should be trivial
case set es _ | call es _ => sorry
case record a => sorry

theorem check_level_checked_succ {e : TypedExpr} {n : Nat}
(h₁ : (checkLevel e n).checked)
: (checkLevel e (1 + n)).checked
:= by
cases e <;> try (simp [checkLevel] at h₁ ; simp [checkLevel])
case ite | and | or | unaryApp =>
simp [h₁, check_level_checked_succ]
case binaryApp op e₀ _ _ =>
cases op <;> (
simp [checkLevel] at h₁
simp [checkLevel]
simp [h₁, check_level_checked_succ]
)
case mem | hasTag | getTag =>
repeat constructor
· have h₂ := check_level_root_invariant (1 + n - 1) (n - 1)
simp [h₂, h₁]
· omega
· have h₂ : (1 + n - 1) = (1 + (n - 1)) := by omega
simp [h₁, h₂, check_level_checked_succ]
case hasAttr e _ _ | getAttr e _ _ =>
split at h₁
· simp [checkLevel] at h₁
simp [checkLevel]
repeat constructor
· have h₂ := check_level_root_invariant (1 + n - 1) (n - 1)
simp [h₂, h₁]
· omega
· have h₂ : (1 + n - 1) = (1 + (n - 1)) := by omega
simp [h₁, h₂, check_level_checked_succ]
· simp [h₁, check_level_checked_succ]
-- should be trivial
case set | call => sorry
case record => sorry
126 changes: 126 additions & 0 deletions cedar-lean/Cedar/Thm/Validation/Levels/Data.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/-
Copyright Cedar Contributors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-/

import Cedar.Data
import Cedar.Thm.Validation.Typechecker.Basic

namespace Cedar.Thm

/-!
This file contains lemma about data structures. These should move into
appropriate files in the `Data` directory, or be replaced by calls to existing
lemma where reasonable.
-/

open Cedar.Data
open Cedar.Spec
open Cedar.Validation

theorem set_mem_flatten_union_iff_mem_any {α : Type} [LT α] [DecidableLT α] {ll : List (Set α)} {e : α}
: e ∈ flatten_union ll ↔ ∃ l ∈ ll, e ∈ l
:= by sorry

theorem map_find_then_value {α β : Type} [BEq α] {m : Map α β} {k : α} {v : β}
(hf : m.find? k = some v)
: v ∈ m.values
:= by sorry

theorem map_find_mapm_value {α β : Type} [LT α] [DecidableLT α] [BEq α] {ks : Set α} {k : α} {kvs : List (α × β)} {fn : α → Option β}
(h₁ : List.mapM (λ k => (fn k).bind λ v => (some (k, v))) ks.elts = some kvs)
(h₂ : k ∈ ks)
: (Map.make kvs).find? k = fn k
:= by
cases h₃ : ks.elts
case nil =>
have hcontra : List.Mem k [] := by
simp only [Membership.mem, h₃] at h₂
exact h₂
contradiction
case cons h t =>
simp [h₃] at h₁
cases h₄ : ((fn h).bind λ v => some (h, v)) <;> simp [h₄] at h₁
cases h₅ : (List.mapM (λ k => (fn k).bind λ v => some (k, v)) t) <;> simp [h₅] at h₁
subst h₁
simp only [Membership.mem, h₃] at h₂
cases h₂
case head =>
cases h₆ : (fn k) <;> simp [h₆] at h₄
subst h₄
sorry
case tail h₂ =>
symm at h₅
sorry

theorem mapm_pair_lookup {α γ : Type} [BEq α] [LawfulBEq α] {l : List α} {l' : List (α × γ)} {f : α → Option (α × γ)} {e: α}
(h₁ : List.mapM f l = some l')
(h₂ : e ∈ l)
(hf : ∀ e, match f e with
| some e' => e'.fst = e
| none => True)
: ∃ e', f e = some e' ∧ l'.lookup e'.fst = some e'.snd
:= by
cases l
case nil => contradiction
case cons h t =>
cases h₃ : f h <;>
cases h₄ : List.mapM f t <;>
simp only [h₃, h₄, List.mapM_cons, Option.pure_def, Option.bind_none_fun, Option.bind_some_fun, Option.some.injEq, reduceCtorEq] at h₁
subst h₁
simp only [List.mem_cons] at h₂
cases h₂
case _ h₂ =>
simp [h₂, h₃, List.lookup]
case _ h₂ =>
have ⟨ e'', ih₁, ih₂ ⟩ := mapm_pair_lookup h₄ h₂ hf
have fh₁ := hf h ; rw [h₃] at fh₁ ; subst fh₁
have fh₂ := hf e ; rw [ih₁] at fh₂ ; subst fh₂
simp only [ih₁,ih₂, Option.some.injEq, List.lookup, exists_eq_left']
split
· rename_i h₅
simp only [beq_iff_eq] at h₅
simp only [←h₅, ih₁, Option.some.injEq] at h₃
rw [h₃]
· simp

theorem map_cons_find_none {α β : Type} [BEq α] [LT α] [DecidableLT α] {e₁ e₂ : α} {v : β} {t : List (α × β)}
(h₁ : e₁ ≠ e₂)
(h₂ : (Map.make t).find? e₁ = none) :
(Map.make ((e₂, v) :: t)).find? e₁ = none
:= by sorry

theorem mapm_none_find_none {α γ : Type} [BEq α] [LT α] [DecidableLT α] {l : List α} {l' : List (α × γ)} {f : α → Option γ} {e: α}
(h₂ : l.mapM (λ e => (f e).bind (λ e' => (e, e'))) = some l')
(h₁ : f e = none) :
(Map.make l').find? e = none
:= by
cases l
case nil =>
simp at h₂
subst h₂
rw [Map.make_nil_is_empty]
simp [Map.find?, Map.empty, Map.kvs]
case cons h t =>
simp at h₂
cases h₃ : (f h) <;> simp [h₃] at h₂
cases h₄ : ((List.mapM (fun e => (f e).bind fun e' => some (e, e')) t)) <;> simp [h₄] at h₂
subst h₂
have ih := mapm_none_find_none h₄ h₁
have hne : e ≠ h := by
intros heq
subst heq
rw [h₁] at h₃
contradiction
apply map_cons_find_none hne ih
Loading