Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
47 changes: 47 additions & 0 deletions Cslib/Foundations/Logic/InferenceSystem.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/-
Copyright (c) 2026 Fabrizio Montesi. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Fabrizio Montesi
-/

module

@[expose] public section

namespace Cslib.Logic

/--
The notation typeclass for inference systems.
This enables the notation `⇓a`, where `a : α` is a derivable value.
-/
class InferenceSystem (α : Type u) where
/--
`⇓a` is a derivation of `a`, that is, a witness that `a` is derivable.
The meaning of this notation is type-dependent.
-/
derivation (s : α) : Sort v

namespace InferenceSystem

@[inherit_doc] scoped notation "⇓" a:90 => InferenceSystem.derivation a

/-- Rewrites the conclusion of a proof into an equal one. -/
@[scoped grind =]
def rwConclusion [InferenceSystem α] {Γ Δ : α} (h : Γ = Δ) (p : ⇓Γ) : ⇓Δ := h ▸ p

/-- `a` is derivable if it is the conclusion of some derivation. -/
def Derivable [InferenceSystem α] (a : α) := Nonempty (⇓a)

/-- Shows derivability from a derivation. -/
def Derivable.fromDerivation [InferenceSystem α] {a : α} (d : ⇓a) : Derivable a := Nonempty.intro d

instance [InferenceSystem α] {a : α} : Coe (⇓a) (Derivable a) := ⟨Derivable.fromDerivation⟩

/-- Extracts (noncomputably) a derivation from the fact that a conclusion is derivable. -/
noncomputable def Derivable.toDerivation [InferenceSystem α] {a : α} (d : Derivable a) : ⇓a := Classical.choice d

noncomputable instance [InferenceSystem α] {a : α} : Coe (Derivable a) (⇓a) := ⟨Derivable.toDerivation⟩

end InferenceSystem

end Cslib.Logic
33 changes: 33 additions & 0 deletions Cslib/Foundations/Logic/LogicalEquivalence.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/-
Copyright (c) 2026 Fabrizio Montesi. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Fabrizio Montesi
-/

module

public import Cslib.Foundations.Syntax.Context
public import Cslib.Foundations.Syntax.Congruence

@[expose] public section

namespace Cslib.Logic

/-- A logical equivalence for a given type of `Judgement`s is a congruence on propositions that
preserves validity of judgements under any judgemental context. -/
class LogicalEquivalence
(Proposition : Type u) [HasContext Proposition]
(Judgement : Type v) [HasHContext Judgement Proposition]
(Valid : Judgement → Sort w) where
/-- The logical equivalence relation. -/
eqv (a b : Proposition) : Prop
/-- Proof that `eqv` is a congruence. -/
[congruence : Congruence Proposition eqv]
/-- Validity is preserved for any judgemental context. -/
eqv_fill_valid (heqv : eqv a b) (c : HasHContext.Context Judgement Proposition)
(h : Valid (c<[a])) : Valid (c<[b])

@[inherit_doc]
scoped infix:29 "" => LogicalEquivalence.eqv

end Cslib.Logic
4 changes: 2 additions & 2 deletions Cslib/Foundations/Syntax/Congruence.lean
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ public import Mathlib.Algebra.Order.Monoid.Unbundled.Defs

namespace Cslib

/-- An equivalence relation preserved by all contexts. -/
/-- An equivalence relation on `α` preserved by all contexts `Ctx`. -/
class Congruence (α : Type*) [HasContext α] (r : α → α → Prop) extends
IsEquiv α r, covariant : CovariantClass (HasContext.Context α) α (·[·]) r
IsEquiv α r, covariant : CovariantClass (HasContext.Context α) α (·<[·]) r

end Cslib
20 changes: 15 additions & 5 deletions Cslib/Foundations/Syntax/Context.lean
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,23 @@ public import Cslib.Init

namespace Cslib

/-- Class for types (`Term`) that have a notion of (single-hole) contexts (`Context`). -/
class HasContext (Term : Sort*) where
/-- Class for types with a canonical notion of heterogeneous single-hole contexts. -/
class HasHContext : Type u) (β : Type v) where
/-- The type of contexts. -/
Context : Sort*
Context : Type*
Comment on lines +16 to +18
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be consistent within a single declaration of Type* versus explicit universes. I'd write

Suggested change
class HasHContext (α : Type u) (β : Type v) where
/-- The type of contexts. -/
Context : Sort*
Context : Type*
class HasHContext (α β : Type*) where
/-- The type of contexts. -/
Context : Type*

/-- Replaces the hole in the context with a value, resulting in a new value. -/
fill (c : Context) (b : β) : α

@[inherit_doc] notation:max c "<[" t "]" => HasHContext.fill c t

/-- Class for types (`α`) that have a canonical notion of homogeneous single-hole contexts
(`Context`). -/
class HasContext (α : Type*) where
/-- The type of contexts. -/
Context : Type*
/-- Replaces the hole in the context with a term. -/
fill (c : Context) (t : Term) : Term
fill (c : Context) (a : α) : α

@[inherit_doc] notation:max c "[" t "]" => HasContext.fill c t
instance [inst : HasContext α] : HasHContext α α := ⟨inst.Context, inst.fill⟩

end Cslib
11 changes: 6 additions & 5 deletions Cslib/Languages/CCS/Basic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -119,18 +119,19 @@ def Context.fill (c : Context Name Constant) (p : Process Name Constant) : Proce
| choiceR r c => Process.choice r (c.fill p)
| res a c => Process.res a (c.fill p)

instance : HasContext (Process Name Constant) := ⟨Context Name Constant, Context.fill⟩
instance : IsContext (Context Name Constant) (Process Name Constant) (Process Name Constant) :=
⟨Context.fill⟩

/-- Definition of context filling. -/
@[scoped grind =]
theorem isContext_def (c : Context Name Constant) (p : Process Name Constant) :
c[p] = c.fill p := rfl
theorem context_fill_def (c : Context Name Constant) (p : Process Name Constant) :
c<[p] = c.fill p := rfl

/-- Any `Process` can be obtained by filling a `Context` with an atom. This proves that `Context`
is a complete formalisation of syntactic contexts for CCS. -/
theorem Context.complete (p : Process Name Constant) :
∃ c : Context Name Constant, p = c[Process.nil] ∨
∃ k : Constant, p = c[Process.const k] := by
∃ c : Context Name Constant, p = c<[Process.nil] ∨
∃ k : Constant, p = c<[Process.const k] := by
induction p
case nil =>
exists hole
Expand Down
107 changes: 107 additions & 0 deletions Cslib/Logics/HML/LogicalEquivalence.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/-
Copyright (c) 2026 Fabrizio Montesi. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Fabrizio Montesi
-/

module

public import Cslib.Logics.HML.Basic
public import Cslib.Foundations.Logic.LogicalEquivalence

@[expose] public section

/-! # Logical Equivalence in HML
This module defines logical equivalence for HML propositions and instantiates `LogicalEquivalence`.
-/

namespace Cslib.Logic.HML

/-- Logical equivalence for HML propositions. -/
@[scoped grind =]
def Proposition.Equiv {State : Type u} {Label : Type v} (a b : Proposition Label) : Prop :=
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get the impression that part of fixing the performance issues in LTS can start with being more strict about Prop-valued def used with grind. I don't quite understand all the new changes around defeq and reducibility, but it seems in general things like this should be a structure or irreducible.

∀ lts : LTS State Label, a.denotation lts = b.denotation lts

/-- Propositional contexts. -/
inductive Proposition.Context (Label : Type u) : Type u where
| hole
| andL (c : Context Label) (φ : Proposition Label)
| andR (φ : Proposition Label) (c : Context Label)
| orL (c : Context Label) (φ : Proposition Label)
| orR (φ : Proposition Label) (c : Context Label)
| diamond (μ : Label) (c : Context Label)
| box (μ : Label) (c : Context Label)

/-- Replaces a hole in a propositional context with a proposition. -/
@[scoped grind =]
def Proposition.Context.fill (c : Context Label) (φ : Proposition Label) :=
match c with
| hole => φ
| andL c φ' => (c.fill φ).and φ'
| andR φ' c => φ'.and (c.fill φ)
| orL c φ' => (c.fill φ).or φ'
| orR φ' c => φ'.or (c.fill φ)
| diamond μ c => .diamond μ (c.fill φ)
| box μ c => .box μ (c.fill φ)

instance : HasContext (Proposition Label) := ⟨Proposition.Context Label, Proposition.Context.fill⟩

open scoped Proposition Proposition.Context

instance : IsEquiv (Proposition Label) (Proposition.Equiv (State := State) (Label := Label)) where
refl := by grind
symm := by grind
trans := by grind

instance {State : Type u} {Label : Type v} :
Congruence (Proposition Label) (Proposition.Equiv (State := State) (Label := Label)) where
elim :
Covariant (Proposition.Context Label) (Proposition Label) (Proposition.Context.fill)
Proposition.Equiv := by
intro ctx a b hab lts
specialize hab lts
induction ctx
<;> simp only [Proposition.Context.fill, Proposition.denotation]
<;> grind
Comment on lines +64 to +66
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's okay to write

Suggested change
induction ctx
<;> simp only [Proposition.Context.fill, Proposition.denotation]
<;> grind
induction ctx <;> simp [Proposition.Context.fill, Proposition.denotation] <;> grind

because grind is considered a tactic permissible to follow the flexible simp. (Though it's not clear to me what is missing that grind won't close this on its own)


/-- Bundled version of a judgement for `Satisfy`. -/
structure Satisfies.Judgement (State : Type u) (Label : Type v) where
lts : LTS State Label
state : State
φ : Proposition Label

/-- `Satisfies` variant using bundled judgements. -/
def Satisfies.Bundled (j : Satisfies.Judgement State Label) := Satisfies j.lts j.state j.φ

@[scoped grind =]
theorem Satisfies.bundled_char : Satisfies.Bundled j ↔ Satisfies j.lts j.state j.φ := by rfl

/-- Judgemental contexts. -/
structure Satisfies.Context (State : Type u) (Label : Type v) where
lts : LTS State Label
state : State

/-- Fills a judgemental context with a proposition. -/
def Satisfies.Context.fill (c : Satisfies.Context State Label) (φ : Proposition Label) :
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a reminder, you can use where with def as well.

Satisfies.Judgement State Label := {
lts := c.lts
state := c.state
φ := φ
}

instance judgementalContext :
HasHContext (Satisfies.Judgement State Label) (Proposition Label) :=
⟨Satisfies.Context State Label, Satisfies.Context.fill⟩

instance : LogicalEquivalence
(Proposition Label) (Satisfies.Judgement State Label) (Satisfies.Bundled) where
eqv := Proposition.Equiv
eqv_fill_valid {a b : Proposition Label} (heqv : a.Equiv (State := State) b)
(c : HasHContext.Context (Satisfies.Judgement State Label) (Proposition Label))
(h : Satisfies.Bundled c<[a]) : Satisfies.Bundled c<[b] := by
simp only [Satisfies.bundled_char, HasHContext.fill, Satisfies.Context.fill]
simp only [Satisfies.bundled_char, HasHContext.fill, Satisfies.Context.fill] at h
grind

end Cslib.Logic.HML
Loading
Loading