Peer of an endpoint send head has an equivalent receive head to Swapping nested restrictions preserves conversion typing
TheoremPeer of an endpoint send head has an equivalent receive head#✓fully proved
Endpoint peer heads preserve literal advertised role/rank, independently equivalent payload and continuation branches, and payload orientation.
theorem endpoint_peer_head {c d : Capability} {r : Role} {k : Nat} {t s : Protocol}
(he : d.Equivalent c.dual) (hh : c.protocol.unfold = .sendEndpoint r k t s) :
∃ v u, d.protocol.unfold = .recvEndpoint r k v u ∧ v.TreeEquiv t ∧ u.TreeEquiv s.dual
structure Capability where
rank : Nat
protocol : Protocol
CSLibExt/Languages/SessionTypes/Endpoint/Context.lean:27
inductive Role where
| positive
| negative
deriving DecidableEq, Repr
CSLibExt/Languages/SessionTypes/Endpoint/Identity.lean:24
inductive Protocol where
| done
| sendName (next : Protocol)
| recvName (next : Protocol)
| sendEndpoint (role : Role) (rank : Nat) (payload next : Protocol)
| recvEndpoint (role : Role) (rank : Nat) (payload next : Protocol)
| regular (graph : Graph) (cursor : Fin graph.size) (reversed : Bool)
CSLibExt/Languages/SessionTypes/Endpoint/Protocol.lean:26
Uses 13 · Used by 4
TheoremInput inversion for conversion typing#✓fully proved
Input inversion retains its actual advertised code and typed continuation.
theorem HasType.inp_inv {n : Nat} {Δ : Context} {a : Name} {p : Proc}
(h : HasType n Δ (.inp a p)) :
∃ e c, e.name = a ∧ Δ.lookup e = some c ∧
((∃ s, c.protocol.unfold = .recvName s ∧
HasType (n + 1) (Context.lift 0 (Δ.insert e ⟨c.rank, s⟩)) p) ∨
∃ r k t s, c.protocol.unfold = .recvEndpoint r k t s ∧
HasType (n + 1)
((Context.lift 0 (Δ.insert e ⟨c.rank, s⟩)).insert ⟨.var 0, r⟩ ⟨k, t⟩) p)
abbrev Context := Finmap (fun _ : Key => Capability)
CSLibExt/Languages/SessionTypes/Endpoint/Context.lean:32
inductive Name where
| const (n : ℕ) : Name
| var (i : ℕ) : Name
deriving DecidableEq, Repr
CSLibExt/Languages/PiCalculus/Basic.lean:45
inductive Proc where
| nil : Proc
| out (a b : Name) (p : Proc) : Proc
| inp (a : Name) (p : Proc) : Proc
| par (p q : Proc) : Proc
| nu (p : Proc) : Proc
| repl (p : Proc) : Proc
| sum (p q : Proc) : Proc
deriving DecidableEq, Repr
CSLibExt/Languages/PiCalculus/Basic.lean:52
inductive HasType : Nat → Context → Proc → Prop where
| nil {n : Nat} {Δ : Context} :
Δ.Completed → (∀ e ∈ Δ, e.name.ClosedAt n) → HasType n Δ .nil
| outName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{b : Name} {s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .sendName s →
e.name.ClosedAt n → b.ClosedAt n →
HasType n (Δ.insert e ⟨c.rank, s⟩) p → HasType n Δ (.out e.name b p)
| inpName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .recvName s → e.name.ClosedAt n →
HasType (n + 1) (Context.lift 0 (Δ.insert e ⟨c.rank, s⟩)) p →
⋯
CSLibExt/Languages/SessionTypes/Endpoint/ConversionTyping.lean:69
def Context.lift (k : Nat) (Δ : Context) : Context :=
rekey (Key.mapName (liftName k)) Δ
(fun _ _ _ _ h => Key.mapName_injective (liftName_injective k) h)
CSLibExt/Languages/SessionTypes/Endpoint/ContextTransport.lean:28
Uses 14 · Used by 2
TheoremPassive head communication preserves conversion typing#✓fully proved
GENERAL passive communicating-head preservation at a semantically compatible actual split, with literal receiver-tail and rank evidence.
theorem passive_head_preservation {n : Nat} {Γ Θ : Context} {e : Key} {c : Capability}
{s : Protocol} {b : Name} {p q : Proc}
(hd : Finmap.Disjoint Γ Θ) (hc : Γ.lookup e = some c)
(hh : c.protocol.unfold = .sendName s)
(hp : HasType n (Γ.insert e ⟨c.rank, s⟩) p) (hq : HasType n Θ (.inp e.name q))
(hb : b.ClosedAt n) (hco : Compatible (Γ ∪ Θ)) :
∃ d u, Θ.lookup e.opposite = some d ∧ d.rank = c.rank ∧
d.protocol.unfold = .recvName u ∧ u.TreeEquiv s.dual ∧
HasType n (((Γ ∪ Θ).insert e ⟨c.rank, s⟩).insert e.opposite ⟨d.rank, u⟩)
(.par p (PiCalculus.subst q b))
abbrev Context := Finmap (fun _ : Key => Capability)
CSLibExt/Languages/SessionTypes/Endpoint/Context.lean:32
structure Key where
name : PiCalculus.Name
role : Role
deriving DecidableEq, Repr
CSLibExt/Languages/SessionTypes/Endpoint/Identity.lean:30
structure Capability where
rank : Nat
protocol : Protocol
CSLibExt/Languages/SessionTypes/Endpoint/Context.lean:27
inductive Protocol where
| done
| sendName (next : Protocol)
| recvName (next : Protocol)
| sendEndpoint (role : Role) (rank : Nat) (payload next : Protocol)
| recvEndpoint (role : Role) (rank : Nat) (payload next : Protocol)
| regular (graph : Graph) (cursor : Fin graph.size) (reversed : Bool)
CSLibExt/Languages/SessionTypes/Endpoint/Protocol.lean:26
inductive Name where
| const (n : ℕ) : Name
| var (i : ℕ) : Name
deriving DecidableEq, Repr
CSLibExt/Languages/PiCalculus/Basic.lean:45
inductive Proc where
| nil : Proc
| out (a b : Name) (p : Proc) : Proc
| inp (a : Name) (p : Proc) : Proc
| par (p q : Proc) : Proc
| nu (p : Proc) : Proc
| repl (p : Proc) : Proc
| sum (p q : Proc) : Proc
deriving DecidableEq, Repr
CSLibExt/Languages/PiCalculus/Basic.lean:52
inductive HasType : Nat → Context → Proc → Prop where
| nil {n : Nat} {Δ : Context} :
Δ.Completed → (∀ e ∈ Δ, e.name.ClosedAt n) → HasType n Δ .nil
| outName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{b : Name} {s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .sendName s →
e.name.ClosedAt n → b.ClosedAt n →
HasType n (Δ.insert e ⟨c.rank, s⟩) p → HasType n Δ (.out e.name b p)
| inpName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .recvName s → e.name.ClosedAt n →
HasType (n + 1) (Context.lift 0 (Δ.insert e ⟨c.rank, s⟩)) p →
⋯
CSLibExt/Languages/SessionTypes/Endpoint/ConversionTyping.lean:69
def Compatible (Δ : Context) : Prop :=
∀ e c d, Δ.lookup e = some c → Δ.lookup e.opposite = some d → d.Equivalent c.dual
CSLibExt/Languages/SessionTypes/Endpoint/ConversionTyping.lean:57
def subst (p : Proc) (n : Name) : Proc := substProc n 0 p
CSLibExt/Languages/PiCalculus/Basic.lean:108
Uses 26 · Used by 1
TheoremEndpoint delegation preserves conversion typing#✓fully proved
At an initially semantically compatible disjoint split, endpoint head communication transfers EXACT v, retaining the receiver's separately equivalent advertised payload/tail codes.
theorem endpoint_head_preservation {n k : Nat} {Γ Θ : Context} {e f : Key}
{c v : Capability} {t s : Protocol} {p q : Proc}
(hd : Finmap.Disjoint Γ Θ) (hc : Γ.lookup e = some c)
(hh : c.protocol.unfold = .sendEndpoint f.role k t s)
(hv : Γ.lookup f = some v) (hvt : v.Equivalent ⟨k, t⟩) (hne : e ≠ f)
(hp : HasType n ((Γ.erase f).insert e ⟨c.rank, s⟩) p)
(hq : HasType n Θ (.inp e.name q)) (hb : f.name.ClosedAt n)
(hco : Compatible (Γ ∪ Θ)) :
∃ d t' u, Θ.lookup e.opposite = some d ∧ d.rank = c.rank ∧
d.protocol.unfold = .recvEndpoint f.role k t' u ∧ t'.TreeEquiv t ∧ u.TreeEquiv s.dual ∧
HasType n (((Γ ∪ Θ).insert e ⟨c.rank, s⟩).insert e.opposite ⟨d.rank, u⟩)
(.par p (PiCalculus.subst q f.name))
abbrev Context := Finmap (fun _ : Key => Capability)
CSLibExt/Languages/SessionTypes/Endpoint/Context.lean:32
structure Key where
name : PiCalculus.Name
role : Role
deriving DecidableEq, Repr
CSLibExt/Languages/SessionTypes/Endpoint/Identity.lean:30
structure Capability where
rank : Nat
protocol : Protocol
CSLibExt/Languages/SessionTypes/Endpoint/Context.lean:27
inductive Protocol where
| done
| sendName (next : Protocol)
| recvName (next : Protocol)
| sendEndpoint (role : Role) (rank : Nat) (payload next : Protocol)
| recvEndpoint (role : Role) (rank : Nat) (payload next : Protocol)
| regular (graph : Graph) (cursor : Fin graph.size) (reversed : Bool)
CSLibExt/Languages/SessionTypes/Endpoint/Protocol.lean:26
inductive Proc where
| nil : Proc
| out (a b : Name) (p : Proc) : Proc
| inp (a : Name) (p : Proc) : Proc
| par (p q : Proc) : Proc
| nu (p : Proc) : Proc
| repl (p : Proc) : Proc
| sum (p q : Proc) : Proc
deriving DecidableEq, Repr
CSLibExt/Languages/PiCalculus/Basic.lean:52
inductive HasType : Nat → Context → Proc → Prop where
| nil {n : Nat} {Δ : Context} :
Δ.Completed → (∀ e ∈ Δ, e.name.ClosedAt n) → HasType n Δ .nil
| outName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{b : Name} {s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .sendName s →
e.name.ClosedAt n → b.ClosedAt n →
HasType n (Δ.insert e ⟨c.rank, s⟩) p → HasType n Δ (.out e.name b p)
| inpName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .recvName s → e.name.ClosedAt n →
HasType (n + 1) (Context.lift 0 (Δ.insert e ⟨c.rank, s⟩)) p →
⋯
CSLibExt/Languages/SessionTypes/Endpoint/ConversionTyping.lean:69
def Compatible (Δ : Context) : Prop :=
∀ e c d, Δ.lookup e = some c → Δ.lookup e.opposite = some d → d.Equivalent c.dual
CSLibExt/Languages/SessionTypes/Endpoint/ConversionTyping.lean:57
def subst (p : Proc) (n : Name) : Proc := substProc n 0 p
CSLibExt/Languages/PiCalculus/Basic.lean:108
Uses 28 · Used by 1
TheoremHead update leaves other lookups unchanged#✓fully proved
Exact two-insert head updates leave every other actual lookup unchanged, without requiring the receiver-tail code to equal the sender's dual.
theorem head_update_other (Δ : Context) (e x : Key) (c d : Capability)
(hx : x ≠ e) (hp : x ≠ e.opposite) :
((Δ.insert e c).insert e.opposite d).lookup x = Δ.lookup x
abbrev Context := Finmap (fun _ : Key => Capability)
CSLibExt/Languages/SessionTypes/Endpoint/Context.lean:32
structure Key where
name : PiCalculus.Name
role : Role
deriving DecidableEq, Repr
CSLibExt/Languages/SessionTypes/Endpoint/Identity.lean:30
structure Capability where
rank : Nat
protocol : Protocol
CSLibExt/Languages/SessionTypes/Endpoint/Context.lean:27
Uses 6 · Used by 4
TheoremHead communication preserves conversion typing#✓fully proved
A typed opposite-head pair at an initially semantically compatible interface yields packed literal-head preservation. Both actual heads and payload/tail correspondence are conclusions, not fields in a protocol or admission predicate.
theorem HasType.head_preservation {n : Nat} {Δ : Context} {a b : Name} {p q : Proc}
(h : HasType n Δ (.par (.out a b p) (.inp a q))) (hco : Compatible Δ) :
∃ e c d s u, e.name = a ∧ Δ.lookup e = some c ∧ Δ.lookup e.opposite = some d ∧
d.rank = c.rank ∧ u.TreeEquiv s.dual ∧
((c.protocol.unfold = .sendName s ∧ d.protocol.unfold = .recvName u) ∨
∃ f v k t t', f.name = b ∧ Δ.lookup f = some v ∧ v.Equivalent ⟨k, t⟩ ∧
c.protocol.unfold = .sendEndpoint f.role k t s ∧
d.protocol.unfold = .recvEndpoint f.role k t' u ∧ t'.TreeEquiv t) ∧
HasType n ((Δ.insert e ⟨c.rank, s⟩).insert e.opposite ⟨d.rank, u⟩)
(.par p (PiCalculus.subst q b))
abbrev Context := Finmap (fun _ : Key => Capability)
CSLibExt/Languages/SessionTypes/Endpoint/Context.lean:32
inductive Name where
| const (n : ℕ) : Name
| var (i : ℕ) : Name
deriving DecidableEq, Repr
CSLibExt/Languages/PiCalculus/Basic.lean:45
inductive Proc where
| nil : Proc
| out (a b : Name) (p : Proc) : Proc
| inp (a : Name) (p : Proc) : Proc
| par (p q : Proc) : Proc
| nu (p : Proc) : Proc
| repl (p : Proc) : Proc
| sum (p q : Proc) : Proc
deriving DecidableEq, Repr
CSLibExt/Languages/PiCalculus/Basic.lean:52
inductive HasType : Nat → Context → Proc → Prop where
| nil {n : Nat} {Δ : Context} :
Δ.Completed → (∀ e ∈ Δ, e.name.ClosedAt n) → HasType n Δ .nil
| outName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{b : Name} {s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .sendName s →
e.name.ClosedAt n → b.ClosedAt n →
HasType n (Δ.insert e ⟨c.rank, s⟩) p → HasType n Δ (.out e.name b p)
| inpName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .recvName s → e.name.ClosedAt n →
HasType (n + 1) (Context.lift 0 (Δ.insert e ⟨c.rank, s⟩)) p →
⋯
CSLibExt/Languages/SessionTypes/Endpoint/ConversionTyping.lean:69
def Compatible (Δ : Context) : Prop :=
∀ e c d, Δ.lookup e = some c → Δ.lookup e.opposite = some d → d.Equivalent c.dual
CSLibExt/Languages/SessionTypes/Endpoint/ConversionTyping.lean:57
def subst (p : Proc) (n : Name) : Proc := substProc n 0 p
CSLibExt/Languages/PiCalculus/Basic.lean:108
Uses 21 · Used by 1
TheoremHead update leaves the transmitted payload slot unchanged#✓fully proved
A transmitted payload slot is literally unchanged in the combined map; its peer role may coexist, but it is neither carrier update key.
theorem endpoint_payload_after {Γ Θ : Context} {e f : Key} {c v : Capability}
(hd : Finmap.Disjoint Γ Θ) (hv : Γ.lookup f = some v) (hp : Θ.lookup e.opposite = some c)
(hne : e ≠ f) (x y : Capability) :
(((Γ ∪ Θ).insert e x).insert e.opposite y).lookup f = some v
abbrev Context := Finmap (fun _ : Key => Capability)
CSLibExt/Languages/SessionTypes/Endpoint/Context.lean:32
structure Key where
name : PiCalculus.Name
role : Role
deriving DecidableEq, Repr
CSLibExt/Languages/SessionTypes/Endpoint/Identity.lean:30
structure Capability where
rank : Nat
protocol : Protocol
CSLibExt/Languages/SessionTypes/Endpoint/Context.lean:27
TheoremLowering a lifted process preserves conversion typing#✓fully proved
Canonical lowering removes only actual outer lifted keys, preserving all conversion typing without a closed-hole restriction.
theorem HasType.unlift {n : Nat} {Γ : Context} {q : Proc}
(h : HasType (n + 1) Γ (liftProc 0 q)) (hΓ : ∀ e ∈ Γ, e.name ≠ .var 0) :
HasType n (Context.lower Γ hΓ) q
abbrev Context := Finmap (fun _ : Key => Capability)
CSLibExt/Languages/SessionTypes/Endpoint/Context.lean:32
inductive Proc where
| nil : Proc
| out (a b : Name) (p : Proc) : Proc
| inp (a : Name) (p : Proc) : Proc
| par (p q : Proc) : Proc
| nu (p : Proc) : Proc
| repl (p : Proc) : Proc
| sum (p q : Proc) : Proc
deriving DecidableEq, Repr
CSLibExt/Languages/PiCalculus/Basic.lean:52
inductive HasType : Nat → Context → Proc → Prop where
| nil {n : Nat} {Δ : Context} :
Δ.Completed → (∀ e ∈ Δ, e.name.ClosedAt n) → HasType n Δ .nil
| outName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{b : Name} {s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .sendName s →
e.name.ClosedAt n → b.ClosedAt n →
HasType n (Δ.insert e ⟨c.rank, s⟩) p → HasType n Δ (.out e.name b p)
| inpName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .recvName s → e.name.ClosedAt n →
HasType (n + 1) (Context.lift 0 (Δ.insert e ⟨c.rank, s⟩)) p →
⋯
CSLibExt/Languages/SessionTypes/Endpoint/ConversionTyping.lean:69
def liftProc (cutoff : ℕ) : Proc → Proc
| .nil => .nil
| .out a b p => .out (liftName cutoff a) (liftName cutoff b) (liftProc cutoff p)
| .inp a p => .inp (liftName cutoff a) (liftProc (cutoff + 1) p)
| .par p q => .par (liftProc cutoff p) (liftProc cutoff q)
| .nu p => .nu (liftProc (cutoff + 1) p)
| .repl p => .repl (liftProc cutoff p)
| .sum p q => .sum (liftProc cutoff p) (liftProc cutoff q)
CSLibExt/Languages/PiCalculus/Basic.lean:70
def Context.lower (Γ : Context) (hΓ : ∀ e ∈ Γ, e.name ≠ .var 0) : Context :=
Context.rekey (Key.mapName (substName (.const 0) 0)) Γ (Context.injOn_lower hΓ)
CSLibExt/Languages/SessionTypes/Endpoint/UnliftContext.lean:53
Uses 14 · Used by 1
TheoremForward scope extrusion preserves conversion typing#✓fully proved
The forward canonical scope rule preserves the exact external context and ambient depth, with the dual pair derived from restriction typing.
theorem HasType.scope_forward {n : Nat} {Δ : Context} {p q : Proc}
(h : HasType n Δ (.par (.nu p) q)) :
HasType n Δ (.nu (.par p (liftProc 0 q)))
abbrev Context := Finmap (fun _ : Key => Capability)
CSLibExt/Languages/SessionTypes/Endpoint/Context.lean:32
inductive Proc where
| nil : Proc
| out (a b : Name) (p : Proc) : Proc
| inp (a : Name) (p : Proc) : Proc
| par (p q : Proc) : Proc
| nu (p : Proc) : Proc
| repl (p : Proc) : Proc
| sum (p q : Proc) : Proc
deriving DecidableEq, Repr
CSLibExt/Languages/PiCalculus/Basic.lean:52
inductive HasType : Nat → Context → Proc → Prop where
| nil {n : Nat} {Δ : Context} :
Δ.Completed → (∀ e ∈ Δ, e.name.ClosedAt n) → HasType n Δ .nil
| outName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{b : Name} {s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .sendName s →
e.name.ClosedAt n → b.ClosedAt n →
HasType n (Δ.insert e ⟨c.rank, s⟩) p → HasType n Δ (.out e.name b p)
| inpName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .recvName s → e.name.ClosedAt n →
HasType (n + 1) (Context.lift 0 (Δ.insert e ⟨c.rank, s⟩)) p →
⋯
CSLibExt/Languages/SessionTypes/Endpoint/ConversionTyping.lean:69
def liftProc (cutoff : ℕ) : Proc → Proc
| .nil => .nil
| .out a b p => .out (liftName cutoff a) (liftName cutoff b) (liftProc cutoff p)
| .inp a p => .inp (liftName cutoff a) (liftProc (cutoff + 1) p)
| .par p q => .par (liftProc cutoff p) (liftProc cutoff q)
| .nu p => .nu (liftProc (cutoff + 1) p)
| .repl p => .repl (liftProc cutoff p)
| .sum p q => .sum (liftProc cutoff p) (liftProc cutoff q)
CSLibExt/Languages/PiCalculus/Basic.lean:70
Uses 15 · Used by 1
TheoremAdding a role unused by the partner preserves conversion typing#✓fully proved
A role missing from one component can be reattached only after actual absence in its typed partner derives completion of the advertised capability.
theorem HasType.insert_from_absent_partner {n : Nat} {Γ Ξ : Context} {p q : Proc}
{e : Key} {c : Capability} (hp : HasType n Γ p) (hq : HasType n Ξ q)
(hc : (Γ ∪ Ξ).lookup e = some c) (hab : NameAbsent e.name q)
(he : e.name.ClosedAt n) : HasType n (Γ.insert e c) p
abbrev Context := Finmap (fun _ : Key => Capability)
CSLibExt/Languages/SessionTypes/Endpoint/Context.lean:32
inductive Proc where
| nil : Proc
| out (a b : Name) (p : Proc) : Proc
| inp (a : Name) (p : Proc) : Proc
| par (p q : Proc) : Proc
| nu (p : Proc) : Proc
| repl (p : Proc) : Proc
| sum (p q : Proc) : Proc
deriving DecidableEq, Repr
CSLibExt/Languages/PiCalculus/Basic.lean:52
structure Key where
name : PiCalculus.Name
role : Role
deriving DecidableEq, Repr
CSLibExt/Languages/SessionTypes/Endpoint/Identity.lean:30
structure Capability where
rank : Nat
protocol : Protocol
CSLibExt/Languages/SessionTypes/Endpoint/Context.lean:27
inductive HasType : Nat → Context → Proc → Prop where
| nil {n : Nat} {Δ : Context} :
Δ.Completed → (∀ e ∈ Δ, e.name.ClosedAt n) → HasType n Δ .nil
| outName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{b : Name} {s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .sendName s →
e.name.ClosedAt n → b.ClosedAt n →
HasType n (Δ.insert e ⟨c.rank, s⟩) p → HasType n Δ (.out e.name b p)
| inpName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .recvName s → e.name.ClosedAt n →
HasType (n + 1) (Context.lift 0 (Δ.insert e ⟨c.rank, s⟩)) p →
⋯
CSLibExt/Languages/SessionTypes/Endpoint/ConversionTyping.lean:69
def NameAbsent (a : Name) : Proc → Prop
| .nil => True
| .out b c p => a ≠ b ∧ a ≠ c ∧ NameAbsent a p
| .inp b p => a ≠ b ∧ NameAbsent (liftName 0 a) p
| .par p q | .sum p q => NameAbsent a p ∧ NameAbsent a q
| .nu p => NameAbsent (liftName 0 a) p
| .repl p => NameAbsent a p
CSLibExt/Languages/SessionTypes/Endpoint/NameAbsence.lean:29
Uses 12 · Used by 1
TheoremRestoring the bound pair to the restricted component#✓fully proved
In the actual scope split, either freshly bound role can be moved back to the restricted component only when partner absence proves it completed.
theorem HasType.restore_scope_pair {n : Nat} {Δ Γ Ξ : Context} {p q : Proc}
{c : Capability} (hp : HasType (n + 1) Γ p)
(hq : HasType (n + 1) Ξ (liftProc 0 q)) (hs : Context.bind c Δ = Γ ∪ Ξ) :
HasType (n + 1) ((Γ.insert (⟨.var 0, .positive⟩ : Key) c).insert
(⟨.var 0, .negative⟩ : Key) c.dual) p
abbrev Context := Finmap (fun _ : Key => Capability)
CSLibExt/Languages/SessionTypes/Endpoint/Context.lean:32
inductive Proc where
| nil : Proc
| out (a b : Name) (p : Proc) : Proc
| inp (a : Name) (p : Proc) : Proc
| par (p q : Proc) : Proc
| nu (p : Proc) : Proc
| repl (p : Proc) : Proc
| sum (p q : Proc) : Proc
deriving DecidableEq, Repr
CSLibExt/Languages/PiCalculus/Basic.lean:52
structure Capability where
rank : Nat
protocol : Protocol
CSLibExt/Languages/SessionTypes/Endpoint/Context.lean:27
inductive HasType : Nat → Context → Proc → Prop where
| nil {n : Nat} {Δ : Context} :
Δ.Completed → (∀ e ∈ Δ, e.name.ClosedAt n) → HasType n Δ .nil
| outName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{b : Name} {s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .sendName s →
e.name.ClosedAt n → b.ClosedAt n →
HasType n (Δ.insert e ⟨c.rank, s⟩) p → HasType n Δ (.out e.name b p)
| inpName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .recvName s → e.name.ClosedAt n →
HasType (n + 1) (Context.lift 0 (Δ.insert e ⟨c.rank, s⟩)) p →
⋯
CSLibExt/Languages/SessionTypes/Endpoint/ConversionTyping.lean:69
def liftProc (cutoff : ℕ) : Proc → Proc
| .nil => .nil
| .out a b p => .out (liftName cutoff a) (liftName cutoff b) (liftProc cutoff p)
| .inp a p => .inp (liftName cutoff a) (liftProc (cutoff + 1) p)
| .par p q => .par (liftProc cutoff p) (liftProc cutoff q)
| .nu p => .nu (liftProc (cutoff + 1) p)
| .repl p => .repl (liftProc cutoff p)
| .sum p q => .sum (liftProc cutoff p) (liftProc cutoff q)
CSLibExt/Languages/PiCalculus/Basic.lean:70
def Context.bind (c : Capability) (Δ : Context) : Context :=
(lift 0 Δ).insert ⟨.var 0, .positive⟩ c |>
Finmap.insert ⟨.var 0, .negative⟩ c.dual
CSLibExt/Languages/SessionTypes/Endpoint/ContextTransport.lean:49
structure Key where
name : PiCalculus.Name
role : Role
deriving DecidableEq, Repr
CSLibExt/Languages/SessionTypes/Endpoint/Identity.lean:30
Uses 16 · Used by 1
TheoremReverse scope extrusion preserves conversion typing#✓fully proved
Reverse scope transport recovers the exact external ownership split from the actual restriction/parallel typing, with no closed-hole premise.
theorem HasType.scope_reverse {n : Nat} {Δ : Context} {p q : Proc}
(h : HasType n Δ (.nu (.par p (liftProc 0 q)))) :
HasType n Δ (.par (.nu p) q)
abbrev Context := Finmap (fun _ : Key => Capability)
CSLibExt/Languages/SessionTypes/Endpoint/Context.lean:32
inductive Proc where
| nil : Proc
| out (a b : Name) (p : Proc) : Proc
| inp (a : Name) (p : Proc) : Proc
| par (p q : Proc) : Proc
| nu (p : Proc) : Proc
| repl (p : Proc) : Proc
| sum (p q : Proc) : Proc
deriving DecidableEq, Repr
CSLibExt/Languages/PiCalculus/Basic.lean:52
inductive HasType : Nat → Context → Proc → Prop where
| nil {n : Nat} {Δ : Context} :
Δ.Completed → (∀ e ∈ Δ, e.name.ClosedAt n) → HasType n Δ .nil
| outName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{b : Name} {s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .sendName s →
e.name.ClosedAt n → b.ClosedAt n →
HasType n (Δ.insert e ⟨c.rank, s⟩) p → HasType n Δ (.out e.name b p)
| inpName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .recvName s → e.name.ClosedAt n →
HasType (n + 1) (Context.lift 0 (Δ.insert e ⟨c.rank, s⟩)) p →
⋯
CSLibExt/Languages/SessionTypes/Endpoint/ConversionTyping.lean:69
def liftProc (cutoff : ℕ) : Proc → Proc
| .nil => .nil
| .out a b p => .out (liftName cutoff a) (liftName cutoff b) (liftProc cutoff p)
| .inp a p => .inp (liftName cutoff a) (liftProc (cutoff + 1) p)
| .par p q => .par (liftProc cutoff p) (liftProc cutoff q)
| .nu p => .nu (liftProc (cutoff + 1) p)
| .repl p => .repl (liftProc cutoff p)
| .sum p q => .sum (liftProc cutoff p) (liftProc cutoff q)
CSLibExt/Languages/PiCalculus/Basic.lean:70
Uses 27 · Used by 1
TheoremScope extrusion preserves conversion typing in both directions#✓fully proved
Both directions of the canonical scope congruence preserve exact external polarized ownership and the unchanged ambient binder depth.
theorem HasType.scope_iff {n : Nat} {Δ : Context} {p q : Proc} :
HasType n Δ (.par (.nu p) q) ↔
HasType n Δ (.nu (.par p (liftProc 0 q)))
abbrev Context := Finmap (fun _ : Key => Capability)
CSLibExt/Languages/SessionTypes/Endpoint/Context.lean:32
inductive Proc where
| nil : Proc
| out (a b : Name) (p : Proc) : Proc
| inp (a : Name) (p : Proc) : Proc
| par (p q : Proc) : Proc
| nu (p : Proc) : Proc
| repl (p : Proc) : Proc
| sum (p q : Proc) : Proc
deriving DecidableEq, Repr
CSLibExt/Languages/PiCalculus/Basic.lean:52
inductive HasType : Nat → Context → Proc → Prop where
| nil {n : Nat} {Δ : Context} :
Δ.Completed → (∀ e ∈ Δ, e.name.ClosedAt n) → HasType n Δ .nil
| outName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{b : Name} {s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .sendName s →
e.name.ClosedAt n → b.ClosedAt n →
HasType n (Δ.insert e ⟨c.rank, s⟩) p → HasType n Δ (.out e.name b p)
| inpName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .recvName s → e.name.ClosedAt n →
HasType (n + 1) (Context.lift 0 (Δ.insert e ⟨c.rank, s⟩)) p →
⋯
CSLibExt/Languages/SessionTypes/Endpoint/ConversionTyping.lean:69
def liftProc (cutoff : ℕ) : Proc → Proc
| .nil => .nil
| .out a b p => .out (liftName cutoff a) (liftName cutoff b) (liftProc cutoff p)
| .inp a p => .inp (liftName cutoff a) (liftProc (cutoff + 1) p)
| .par p q => .par (liftProc cutoff p) (liftProc cutoff q)
| .nu p => .nu (liftProc (cutoff + 1) p)
| .repl p => .repl (liftProc cutoff p)
| .sum p q => .sum (liftProc cutoff p) (liftProc cutoff q)
CSLibExt/Languages/PiCalculus/Basic.lean:70
Uses 6 · Used by 1
TheoremParallel commutation preserves conversion typing#✓fully proved
Parallel commutation swaps a derived disjoint split, not its capabilities.
theorem HasType.par_comm {n : Nat} {Δ : Context} {p q : Proc}
(h : HasType n Δ (.par p q)) : HasType n Δ (.par q p)
abbrev Context := Finmap (fun _ : Key => Capability)
CSLibExt/Languages/SessionTypes/Endpoint/Context.lean:32
inductive Proc where
| nil : Proc
| out (a b : Name) (p : Proc) : Proc
| inp (a : Name) (p : Proc) : Proc
| par (p q : Proc) : Proc
| nu (p : Proc) : Proc
| repl (p : Proc) : Proc
| sum (p q : Proc) : Proc
deriving DecidableEq, Repr
CSLibExt/Languages/PiCalculus/Basic.lean:52
inductive HasType : Nat → Context → Proc → Prop where
| nil {n : Nat} {Δ : Context} :
Δ.Completed → (∀ e ∈ Δ, e.name.ClosedAt n) → HasType n Δ .nil
| outName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{b : Name} {s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .sendName s →
e.name.ClosedAt n → b.ClosedAt n →
HasType n (Δ.insert e ⟨c.rank, s⟩) p → HasType n Δ (.out e.name b p)
| inpName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .recvName s → e.name.ClosedAt n →
HasType (n + 1) (Context.lift 0 (Δ.insert e ⟨c.rank, s⟩)) p →
⋯
CSLibExt/Languages/SessionTypes/Endpoint/ConversionTyping.lean:69
Uses 8 · Used by 1
TheoremParallel reassociation preserves conversion typing#✓fully proved
Parallel reassociation preserves the actual three-way disjoint split.
theorem HasType.par_assoc {n : Nat} {Δ : Context} {p q r : Proc}
(h : HasType n Δ (.par (.par p q) r)) :
HasType n Δ (.par p (.par q r))
abbrev Context := Finmap (fun _ : Key => Capability)
CSLibExt/Languages/SessionTypes/Endpoint/Context.lean:32
inductive Proc where
| nil : Proc
| out (a b : Name) (p : Proc) : Proc
| inp (a : Name) (p : Proc) : Proc
| par (p q : Proc) : Proc
| nu (p : Proc) : Proc
| repl (p : Proc) : Proc
| sum (p q : Proc) : Proc
deriving DecidableEq, Repr
CSLibExt/Languages/PiCalculus/Basic.lean:52
inductive HasType : Nat → Context → Proc → Prop where
| nil {n : Nat} {Δ : Context} :
Δ.Completed → (∀ e ∈ Δ, e.name.ClosedAt n) → HasType n Δ .nil
| outName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{b : Name} {s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .sendName s →
e.name.ClosedAt n → b.ClosedAt n →
HasType n (Δ.insert e ⟨c.rank, s⟩) p → HasType n Δ (.out e.name b p)
| inpName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .recvName s → e.name.ClosedAt n →
HasType (n + 1) (Context.lift 0 (Δ.insert e ⟨c.rank, s⟩)) p →
⋯
CSLibExt/Languages/SessionTypes/Endpoint/ConversionTyping.lean:69
Uses 8 · Used by 1
TheoremReverse parallel reassociation preserves conversion typing#✓fully proved
Reverse reassociation recovers both sub-splits from the supplied typing.
theorem HasType.par_assoc_reverse {n : Nat} {Δ : Context} {p q r : Proc}
(h : HasType n Δ (.par p (.par q r))) :
HasType n Δ (.par (.par p q) r)
abbrev Context := Finmap (fun _ : Key => Capability)
CSLibExt/Languages/SessionTypes/Endpoint/Context.lean:32
inductive Proc where
| nil : Proc
| out (a b : Name) (p : Proc) : Proc
| inp (a : Name) (p : Proc) : Proc
| par (p q : Proc) : Proc
| nu (p : Proc) : Proc
| repl (p : Proc) : Proc
| sum (p q : Proc) : Proc
deriving DecidableEq, Repr
CSLibExt/Languages/PiCalculus/Basic.lean:52
inductive HasType : Nat → Context → Proc → Prop where
| nil {n : Nat} {Δ : Context} :
Δ.Completed → (∀ e ∈ Δ, e.name.ClosedAt n) → HasType n Δ .nil
| outName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{b : Name} {s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .sendName s →
e.name.ClosedAt n → b.ClosedAt n →
HasType n (Δ.insert e ⟨c.rank, s⟩) p → HasType n Δ (.out e.name b p)
| inpName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .recvName s → e.name.ClosedAt n →
HasType (n + 1) (Context.lift 0 (Δ.insert e ⟨c.rank, s⟩)) p →
⋯
CSLibExt/Languages/SessionTypes/Endpoint/ConversionTyping.lean:69
Uses 8 · Used by 1
TheoremAdding a parallel nil preserves conversion typing#✓fully proved
Adding a parallel nil allocates it no ownership; no active slot is dropped.
theorem HasType.par_nil_intro {n : Nat} {Δ : Context} {p : Proc}
(h : HasType n Δ p) : HasType n Δ (.par p .nil)
abbrev Context := Finmap (fun _ : Key => Capability)
CSLibExt/Languages/SessionTypes/Endpoint/Context.lean:32
inductive Proc where
| nil : Proc
| out (a b : Name) (p : Proc) : Proc
| inp (a : Name) (p : Proc) : Proc
| par (p q : Proc) : Proc
| nu (p : Proc) : Proc
| repl (p : Proc) : Proc
| sum (p q : Proc) : Proc
deriving DecidableEq, Repr
CSLibExt/Languages/PiCalculus/Basic.lean:52
inductive HasType : Nat → Context → Proc → Prop where
| nil {n : Nat} {Δ : Context} :
Δ.Completed → (∀ e ∈ Δ, e.name.ClosedAt n) → HasType n Δ .nil
| outName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{b : Name} {s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .sendName s →
e.name.ClosedAt n → b.ClosedAt n →
HasType n (Δ.insert e ⟨c.rank, s⟩) p → HasType n Δ (.out e.name b p)
| inpName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .recvName s → e.name.ClosedAt n →
HasType (n + 1) (Context.lift 0 (Δ.insert e ⟨c.rank, s⟩)) p →
⋯
CSLibExt/Languages/SessionTypes/Endpoint/ConversionTyping.lean:69
Uses 11 · Used by 1
TheoremRemoving a restriction around nil preserves conversion typing#✓fully proved
Restriction of nil has exactly the completed external ownership of nil.
theorem HasType.nu_nil_elim {n : Nat} {Δ : Context}
(h : HasType n Δ (.nu .nil)) : HasType n Δ .nil
abbrev Context := Finmap (fun _ : Key => Capability)
CSLibExt/Languages/SessionTypes/Endpoint/Context.lean:32
inductive HasType : Nat → Context → Proc → Prop where
| nil {n : Nat} {Δ : Context} :
Δ.Completed → (∀ e ∈ Δ, e.name.ClosedAt n) → HasType n Δ .nil
| outName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{b : Name} {s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .sendName s →
e.name.ClosedAt n → b.ClosedAt n →
HasType n (Δ.insert e ⟨c.rank, s⟩) p → HasType n Δ (.out e.name b p)
| inpName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .recvName s → e.name.ClosedAt n →
HasType (n + 1) (Context.lift 0 (Δ.insert e ⟨c.rank, s⟩)) p →
⋯
CSLibExt/Languages/SessionTypes/Endpoint/ConversionTyping.lean:69
Uses 15 · Used by 2
TheoremAdding a restriction around nil preserves conversion typing#✓fully proved
A completed fresh pair may be introduced around nil while retaining all original external capabilities and scope.
theorem HasType.nu_nil_intro {n : Nat} {Δ : Context}
(h : HasType n Δ .nil) : HasType n Δ (.nu .nil)
abbrev Context := Finmap (fun _ : Key => Capability)
CSLibExt/Languages/SessionTypes/Endpoint/Context.lean:32
inductive HasType : Nat → Context → Proc → Prop where
| nil {n : Nat} {Δ : Context} :
Δ.Completed → (∀ e ∈ Δ, e.name.ClosedAt n) → HasType n Δ .nil
| outName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{b : Name} {s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .sendName s →
e.name.ClosedAt n → b.ClosedAt n →
HasType n (Δ.insert e ⟨c.rank, s⟩) p → HasType n Δ (.out e.name b p)
| inpName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .recvName s → e.name.ClosedAt n →
HasType (n + 1) (Context.lift 0 (Δ.insert e ⟨c.rank, s⟩)) p →
⋯
CSLibExt/Languages/SessionTypes/Endpoint/ConversionTyping.lean:69
Uses 15 · Used by 2
TheoremSwapping nested restrictions preserves conversion typing#✓fully proved
Nested restriction commutation swaps their derived complete dual pairs.
theorem HasType.nu_swap {n : Nat} {Δ : Context} {p : Proc}
(h : HasType n Δ (.nu (.nu p))) :
HasType n Δ (.nu (.nu (swapProc 0 p)))
abbrev Context := Finmap (fun _ : Key => Capability)
CSLibExt/Languages/SessionTypes/Endpoint/Context.lean:32
inductive Proc where
| nil : Proc
| out (a b : Name) (p : Proc) : Proc
| inp (a : Name) (p : Proc) : Proc
| par (p q : Proc) : Proc
| nu (p : Proc) : Proc
| repl (p : Proc) : Proc
| sum (p q : Proc) : Proc
deriving DecidableEq, Repr
CSLibExt/Languages/PiCalculus/Basic.lean:52
inductive HasType : Nat → Context → Proc → Prop where
| nil {n : Nat} {Δ : Context} :
Δ.Completed → (∀ e ∈ Δ, e.name.ClosedAt n) → HasType n Δ .nil
| outName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{b : Name} {s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .sendName s →
e.name.ClosedAt n → b.ClosedAt n →
HasType n (Δ.insert e ⟨c.rank, s⟩) p → HasType n Δ (.out e.name b p)
| inpName {n : Nat} {Δ : Context} {e : Key} {c : Capability}
{s : Protocol} {p : Proc} :
Δ.lookup e = some c → c.protocol.unfold = .recvName s → e.name.ClosedAt n →
HasType (n + 1) (Context.lift 0 (Δ.insert e ⟨c.rank, s⟩)) p →
⋯
CSLibExt/Languages/SessionTypes/Endpoint/ConversionTyping.lean:69
def swapProc (cutoff : ℕ) : Proc → Proc
| .nil => .nil
| .out a b p => .out (swapNameAt cutoff a) (swapNameAt cutoff b) (swapProc cutoff p)
| .inp a p => .inp (swapNameAt cutoff a) (swapProc (cutoff + 1) p)
| .par p q => .par (swapProc cutoff p) (swapProc cutoff q)
| .nu p => .nu (swapProc (cutoff + 1) p)
| .repl p => .repl (swapProc cutoff p)
| .sum p q => .sum (swapProc cutoff p) (swapProc cutoff q)
CSLibExt/Languages/PiCalculus/Basic.lean:119
Uses 10 · Used by 2
Loading dependency explorer…
The dependency explorer needs JavaScript and its graph data.