Research source · Plain text
Contexts.lean
site/public/formal/boundary-context/Contexts.lean
150 lines. Source is displayed for inspection; it is not executed by this page.
File fingerprint
SHA-256: 96b59f5dfba83ed14aa1aaa0accb4c520c4f76bc007e98b663ff19d39614e5c6
import Fragments
namespace FPRD.Boundary
/-- Only bijective boundary renaming is a public context operation. -/
structure BoundaryEquiv (B C : Type) where
toFun : B → C
invFun : C → B
left_inv : ∀ b, invFun (toFun b) = b
right_inv : ∀ c, toFun (invFun c) = c
/-- A finite client expression, allowing zero, one or many uses of its input.
Each Join gives its two occurrences fresh private namespaces. -/
inductive Client (B : Type) : Type → Type 1 where
| hole : Client B B
| const {C : Type} (F : Fragment C) : Client B C
| join {C : Type} (left right : Client B C) : Client B C
| introduce {C : Type} (body : Client B C) : Client B (Option C)
| forget {C : Type} (body : Client B (Option C)) : Client B C
| rename {C D : Type} (e : BoundaryEquiv C D) (body : Client B C) : Client B D
| pin {C : Type} (v : C) (value : Bool) (body : Client B C) : Client B C
namespace Client
def eval {B C : Type} (F : Fragment B) : Client B C → Fragment C
| .hole => F
| .const G => G
| .join L R => (eval F L).join (eval F R)
| .introduce K => (eval F K).introduce
| .forget K => (eval F K).forget
| .rename e K => (eval F K).renameBoundary e.toFun
| .pin v value K => (eval F K).pin v value
end Client
/-- Equality of boundary relations, stated extensionally. -/
def RelEq {B : Type} (F G : Fragment B) : Prop :=
∀ a, F.rel a ↔ G.rel a
def Sat {B : Type} (F : Fragment B) : Prop := ∃ a, F.rel a
/-- Observations are only satisfiability of finite client expressions. -/
def ContextualEq {B : Type} (F G : Fragment B) : Prop :=
∀ (C : Type) (K : Client B C), Sat (K.eval F) ↔ Sat (K.eval G)
theorem client_congruence {B C : Type} {F G : Fragment B}
(h : RelEq F G) (K : Client B C) : RelEq (K.eval F) (K.eval G) := by
induction K with
| hole => exact h
| const P => intro a; rfl
| join L R ihL ihR =>
intro a
simp only [Client.eval, Fragment.rel_join]
exact and_congr (ihL a) (ihR a)
| introduce K ih =>
intro a
simp only [Client.eval, Fragment.rel_introduce]
exact ih _
| forget K ih =>
intro a
simp only [Client.eval, Fragment.rel_forget]
exact exists_congr (fun value => ih _)
| rename e K ih =>
intro a
simp only [Client.eval, Fragment.rel_renameBoundary]
exact ih _
| pin v value K ih =>
intro a
simp only [Client.eval, Fragment.rel_pin]
exact and_congr (ih a) Iff.rfl
theorem relEq_implies_contextualEq {B : Type} {F G : Fragment B}
(h : RelEq F G) : ContextualEq F G := by
intro C K
exact exists_congr (client_congruence h K)
/-- Pin every listed boundary name, using a finite sequence of signed units. -/
def pinAll {B : Type} (xs : List B) (a : B → Bool) : Client B B :=
match xs with
| [] => .hole
| v :: vs => .pin v (a v) (pinAll vs a)
theorem rel_pinAll {B : Type} (F : Fragment B) (xs : List B)
(a b : B → Bool) :
((pinAll xs a).eval F).rel b ↔ F.rel b ∧ ∀ v ∈ xs, b v = a v := by
induction xs with
| nil => simp [pinAll, Client.eval]
| cons v vs ih =>
simp only [pinAll, Client.eval, Fragment.rel_pin, ih]
constructor
· intro h
refine ⟨h.1.1, ?_⟩
intro w hw
cases List.mem_cons.mp hw with
| inl heq => simpa [heq] using h.2
| inr hm => exact h.1.2 w hm
· intro h
exact ⟨⟨h.1, fun w hw => h.2 w (List.mem_cons.mpr (Or.inr hw))⟩,
h.2 v (List.mem_cons.mpr (Or.inl rfl))⟩
/-- A finite separating test: its SAT answer is exactly membership of a. -/
theorem sat_pinAll {B : Type} (F : Fragment B) (xs : List B)
(covers : ∀ v, v ∈ xs) (a : B → Bool) :
Sat ((pinAll xs a).eval F) ↔ F.rel a := by
constructor
· rintro ⟨b, hb⟩
have q := (rel_pinAll F xs a b).mp hb
have e : b = a := funext (fun v => q.2 v (covers v))
simpa [e] using q.1
· intro h
exact ⟨a, (rel_pinAll F xs a a).mpr ⟨h, fun _ _ => rfl⟩⟩
/-- Complete boundary invariant for every finitely enumerated boundary.
Duplicates in xs are harmless. No bound on private variables or client depth. -/
theorem contextualEq_iff_relEq {B : Type} (xs : List B)
(covers : ∀ v, v ∈ xs) (F G : Fragment B) :
ContextualEq F G ↔ RelEq F G := by
constructor
· intro h a
exact (sat_pinAll F xs covers a).symm.trans
((h B (pinAll xs a)).trans (sat_pinAll G xs covers a))
· exact relEq_implies_contextualEq
/-- The same complete invariant stated as actual equality of predicates. -/
theorem contextualEq_iff_boundary_eq {B : Type} (xs : List B)
(covers : ∀ v, v ∈ xs) (F G : Fragment B) :
ContextualEq F G ↔ F.rel = G.rel := by
constructor
· intro h
exact funext (fun a => propext
((contextualEq_iff_relEq xs covers F G).mp h a))
· intro h
apply relEq_implies_contextualEq
intro a
rw [h]
/-- The relation is a minimal exact invariant in the kernel-refinement sense:
any summary identifying only contextually equivalent fragments also identifies
only equal boundary relations. This does not assert a resource bound. -/
theorem exact_summary_refines_relation {B S : Type}
(xs : List B) (covers : ∀ v, v ∈ xs) (summary : Fragment B → S)
(sound : ∀ F G, summary F = summary G → ContextualEq F G)
(F G : Fragment B) (same : summary F = summary G) : RelEq F G :=
(contextualEq_iff_relEq xs covers F G).mp (sound F G same)
#print axioms client_congruence
#print axioms contextualEq_iff_relEq
#print axioms exact_summary_refines_relation
end FPRD.Boundary