Jon Sterling, started 16th Dec 2022 A deductive system is a category-like structure in that omits the associativity law; associativity of pre-and-post-composition then begins a *property* of certain morphisms. This captures the behavior of *effectful* programs, whose composition is not also associative; this perspective of effectful programs arises from an analysis of the dynamics of cut elimination in polarized sequent calculus. For this reason, we denote morphisms by `A ⊢ B` and write `cut` for the (non-associative) composition operation. \begin{code} {-# OPTIONS --safe --without-K #-} open import UF.FunExt module Duploids.DeductiveSystem (fe : Fun-Ext) where open import UF.Equiv open import MLTT.Spartan open import UF.Subsingletons open import UF.Subsingletons-FunExt open import Categories.Category fe deductive-system-structure : (𝓤 𝓥 : Universe) → (𝓤 ⊔ 𝓥)⁺ ̇ deductive-system-structure 𝓤 𝓥 = category-structure 𝓤 𝓥 module deductive-system-structure (𝓓 : deductive-system-structure 𝓤 𝓥) where ob : 𝓤 ̇ ob = pr₁ 𝓓 _⊢_ : ob → ob → 𝓥 ̇ A ⊢ B = pr₁ (pr₂ 𝓓) A B idn : (A : ob) → A ⊢ A idn A = pr₁ (pr₂ (pr₂ 𝓓)) A cut : {A B C : ob} (f : A ⊢ B) (g : B ⊢ C) → A ⊢ C cut f g = pr₂ (pr₂ (pr₂ 𝓓)) _ _ _ f g module _ (𝓓 : deductive-system-structure 𝓤 𝓥) where open deductive-system-structure 𝓓 open category-axiom-statements 𝓓 deductive-system-axioms : 𝓤 ⊔ 𝓥 ̇ deductive-system-axioms = statement-hom-is-set × statement-idn-L × statement-idn-R module deductive-system-axioms (ax : deductive-system-axioms) where ⊢-is-set : statement-hom-is-set ⊢-is-set = pr₁ ax idn-L : statement-idn-L idn-L = pr₁ (pr₂ ax) idn-R : statement-idn-R idn-R = pr₂ (pr₂ ax) record deductive-system (𝓤 𝓥 : Universe) : (𝓤 ⊔ 𝓥)⁺ ̇ where constructor make field str : deductive-system-structure 𝓤 𝓥 ax : deductive-system-axioms str open deductive-system-structure str public open deductive-system-axioms str ax public module deductive-system-as-sum {𝓤 𝓥 : Universe} where to-sum : deductive-system 𝓤 𝓥 → Σ str ꞉ deductive-system-structure 𝓤 𝓥 , deductive-system-axioms str to-sum 𝓓 = let open deductive-system 𝓓 in str , ax from-sum : (Σ str ꞉ deductive-system-structure 𝓤 𝓥 , deductive-system-axioms str) → deductive-system 𝓤 𝓥 from-sum 𝓓 = make (pr₁ 𝓓) (pr₂ 𝓓) to-sum-is-equiv : is-equiv to-sum pr₁ (pr₁ to-sum-is-equiv) = from-sum pr₂ (pr₁ to-sum-is-equiv) _ = refl pr₁ (pr₂ to-sum-is-equiv) = from-sum pr₂ (pr₂ to-sum-is-equiv) _ = refl equiv : deductive-system 𝓤 𝓥 ≃ (Σ str ꞉ deductive-system-structure 𝓤 𝓥 , deductive-system-axioms str) equiv = to-sum , to-sum-is-equiv \end{code} We now begin to state the associativity properties that hold of certain morphisms. A morphism `f` is "thunkable" when precomposing by it is associative in the sense that `f; (g; h) = (f; g); h`; such morphisms correspond to "values" in programming languages. On the other hand, a morphism `f` is "linear" when postcomposing by it is associative; such morphisms correspond to "stacks" in programming languages. \begin{code} module ⊢-properties (𝓓 : deductive-system 𝓤 𝓥) where open deductive-system 𝓓 module _ {A B : ob} (f : A ⊢ B) where is-thunkable : 𝓤 ⊔ 𝓥 ̇ is-thunkable = (C D : ob) (g : B ⊢ C) (h : C ⊢ D) → cut (cut f g) h = cut f (cut g h) is-linear : 𝓤 ⊔ 𝓥 ̇ is-linear = (U V : ob) (g : V ⊢ A) (h : U ⊢ V) → cut (cut h g) f = (cut h (cut g f)) \end{code} Just as in a category, we can speak of a map being inverse to another map. Note however that without additional assumptions, inverses do not seem to be unique. \begin{code} is-inverse : (g : B ⊢ A) → 𝓥 ̇ is-inverse g = (cut f g = idn _) × (cut g f = idn _) being-inverse-is-prop : {g : B ⊢ A} → is-prop (is-inverse g) being-inverse-is-prop = ×-is-prop (⊢-is-set _ _) (⊢-is-set _ _) \end{code} Because the identity laws hold, identity morphisms are both linear and thunkable. Furthermore, the composition of (linear, thunkable) morphisms is (linear, thunkable). \begin{code} module _ (A : ob) where abstract idn-linear : is-linear (idn A) idn-linear U V g h = cut (cut h g) (idn A) =⟨ idn-R _ _ _ ⟩ cut h g =⟨ ap (cut h) (idn-R _ _ _ ⁻¹) ⟩ cut h (cut g (idn A)) ∎ idn-thunkable : is-thunkable (idn A) idn-thunkable C D g h = cut (cut (idn A) g) h =⟨ ap (λ x → cut x h) (idn-L A C g) ⟩ cut g h =⟨ idn-L A D (cut g h) ⁻¹ ⟩ cut (idn A) (cut g h) ∎ module _ {A B C : ob} (f : A ⊢ B) (g : B ⊢ C) where abstract cut-linear : is-linear f → is-linear g → is-linear (cut f g) cut-linear f-lin g-lin U V h k = cut (cut k h) (cut f g) =⟨ g-lin U A f (cut k h) ⁻¹ ⟩ cut (cut (cut k h) f) g =⟨ ap (λ x → cut x g) (f-lin U V h k) ⟩ cut (cut k (cut h f)) g =⟨ g-lin U V (cut h f) k ⟩ cut k (cut (cut h f) g) =⟨ ap (cut k) (g-lin V A f h) ⟩ cut k (cut h (cut f g)) ∎ cut-thunkable : is-thunkable f → is-thunkable g → is-thunkable (cut f g) cut-thunkable f-th g-th D E h k = cut (cut (cut f g) h) k =⟨ ap (λ x → cut x k) (f-th C D g h) ⟩ cut (cut f (cut g h)) k =⟨ f-th D E (cut g h) k ⟩ cut f (cut (cut g h) k) =⟨ ap (cut f) (g-th D E h k) ⟩ cut f (cut g (cut h k)) =⟨ f-th C E g (cut h k) ⁻¹ ⟩ cut (cut f g) (cut h k) ∎ module _ {A B} {f : A ⊢ B} where being-thunkable-is-prop : is-prop (is-thunkable f) being-thunkable-is-prop = Π-is-prop fe λ _ → Π-is-prop fe λ _ → Π-is-prop fe λ _ → Π-is-prop fe λ _ → ⊢-is-set _ _ being-linear-is-prop : is-prop (is-linear f) being-linear-is-prop = Π-is-prop fe λ _ → Π-is-prop fe λ _ → Π-is-prop fe λ _ → Π-is-prop fe λ _ → ⊢-is-set _ _ \end{code} Although inverses need not in general be unique, an inverse *is* unique if it is either linear or thunkable. \begin{code} module _ {A B} {f : A ⊢ B} {g g'} (fg : is-inverse f g) (fg' : is-inverse f g') where linear-inverse-is-unique : is-linear g → g' = g linear-inverse-is-unique g-lin = g' =⟨ idn-R B A _ ⁻¹ ⟩ cut _ (idn _) =⟨ ap (cut _) (pr₁ fg ⁻¹) ⟩ cut _ (cut f _) =⟨ g-lin B A f _ ⁻¹ ⟩ cut (cut _ f) _ =⟨ ap (λ x → cut x g) (pr₂ fg') ⟩ cut (idn _) g =⟨ idn-L B A g ⟩ g ∎ thunkable-inverse-is-unique : is-thunkable g → g' = g thunkable-inverse-is-unique g-th = g' =⟨ idn-L B A g' ⁻¹ ⟩ cut (idn _) g' =⟨ ap (λ x → cut x g') (pr₂ fg ⁻¹) ⟩ cut (cut g f) g' =⟨ g-th B A f g' ⟩ cut g (cut f g') =⟨ ap (cut g) (pr₁ fg') ⟩ cut g (idn _) =⟨ idn-R B A g ⟩ g ∎ \end{code} An object `A` in a deductive system such that every morphism out of `A` is linear is called "positive"; conversely, when every morphism into `A` is thunkable we call `A` "negative". This is an extensional / objective account of the syntactical phenomenon of polarity in structural proof theory. \begin{code} module polarities (𝓓 : deductive-system 𝓤 𝓥) where open deductive-system 𝓓 open ⊢-properties 𝓓 module _ (A : ob) where is-positive : 𝓤 ⊔ 𝓥 ̇ is-positive = (B : ob) (f : A ⊢ B) → is-linear f is-negative : 𝓤 ⊔ 𝓥 ̇ is-negative = (B : ob) (f : B ⊢ A) → is-thunkable f module _ {A} where being-positive-is-prop : is-prop (is-positive A) being-positive-is-prop = Π-is-prop fe λ _ → Π-is-prop fe λ _ → being-linear-is-prop being-negative-is-prop : is-prop (is-negative A) being-negative-is-prop = Π-is-prop fe λ _ → Π-is-prop fe λ _ → being-thunkable-is-prop \end{code}