module CombinatoryLogic.Equality where
open import Algebra.Definitions using (Congruent₂; LeftCongruent; RightCongruent)
open import Data.Vec using (Vec; []; _∷_; foldr₁; lookup)
open import Function using (_$_)
open import Relation.Binary using (IsEquivalence; Setoid)
open import Relation.Binary.PropositionalEquality using (_≡_; refl)
open import CombinatoryLogic.Semantics
open import CombinatoryLogic.Syntax
private
lemma-CQXX : ∀ {X} → ⊢ C ∙ Q ∙ X ∙ X
lemma-CQXX {X} =
let s₁ = ⊢ Π ∙ (W ∙ (C ∙ Q)) [ ax Q ]
s₂ = ⊢ W ∙ (C ∙ Q) ∙ X [ Π s₁ ]
s₃ = ⊢ Q ∙ (W ∙ (C ∙ Q) ∙ X) ∙ (C ∙ Q ∙ X ∙ X) [ W ]
s₄ = ⊢ C ∙ Q ∙ X ∙ X [ Q₁ s₂ s₃ ]
in s₄
prop₁ : ∀ {X} → ⊢ Q ∙ X ∙ X
prop₁ {X} = s₆ where
s₄ = ⊢ C ∙ Q ∙ X ∙ X [ lemma-CQXX ]
s₅ = ⊢ Q ∙ (C ∙ Q ∙ X ∙ X) ∙ (Q ∙ X ∙ X) [ C ]
s₆ = ⊢ Q ∙ X ∙ X [ Q₁ s₄ s₅ ]
prop₂ : ∀ {X Y} → ⊢ Q ∙ X ∙ Y → ⊢ Q ∙ Y ∙ X
prop₂ {X} {Y} ⊢QXY = s₅ where
s₁ = ⊢ Q ∙ X ∙ Y [ ⊢QXY ]
s₂ = ⊢ Q ∙ (C ∙ Q ∙ X ∙ X) ∙ (C ∙ Q ∙ X ∙ Y) [ Q₂ {Z = C ∙ Q ∙ X} s₁ ]
s₃ = ⊢ C ∙ Q ∙ X ∙ X [ lemma-CQXX ]
s₄ = ⊢ C ∙ Q ∙ X ∙ Y [ Q₁ s₃ s₂ ]
s₅ = ⊢ Q ∙ Y ∙ X [ Q₁ s₄ C ]
prop₃ : ∀ {X Y Z} → ⊢ Q ∙ X ∙ Y → ⊢ Q ∙ Y ∙ Z → ⊢ Q ∙ X ∙ Z
prop₃ {X} {Y} {Z} ⊢QXY ⊢QYZ = s₃ where
s₁ = ⊢ Q ∙ Y ∙ Z [ ⊢QYZ ]
s₂ = ⊢ Q ∙ (Q ∙ X ∙ Y) ∙ (Q ∙ X ∙ Z) [ Q₂ {Z = Q ∙ X} s₁ ]
s₃ = ⊢ Q ∙ X ∙ Z [ Q₁ ⊢QXY s₂ ]
prop₄ : ∀ {X Y Z} → ⊢ Q ∙ X ∙ Y → ⊢ Q ∙ (X ∙ Z) ∙ (Y ∙ Z)
prop₄ {X} {Y} {Z} Hp = s₅ where
p₁ = λ {X} → ⊢ Q ∙ (C ∙ (B ∙ (W ∙ K)) ∙ Z ∙ X) ∙ (B ∙ (W ∙ K) ∙ X ∙ Z) [ C ]
p₂ = λ {X} → ⊢ Q ∙ (B ∙ (W ∙ K) ∙ X ∙ Z) ∙ (W ∙ K ∙ (X ∙ Z)) [ B ]
p₃ = λ {X} → ⊢ Q ∙ (W ∙ K ∙ (X ∙ Z)) ∙ (K ∙ (X ∙ Z) ∙ (X ∙ Z)) [ W ]
p₄ = λ {X} → ⊢ Q ∙ (K ∙ (X ∙ Z) ∙ (X ∙ Z)) ∙ (X ∙ Z) [ K ]
p₅ = λ {X} → ⊢ Q ∙ (C ∙ (B ∙ (W ∙ K)) ∙ Z ∙ X) ∙ (X ∙ Z) [ prop₃ p₁ $ prop₃ p₂ $ prop₃ p₃ p₄ ]
s₁ = ⊢ Q ∙ (C ∙ (B ∙ (W ∙ K)) ∙ Z ∙ X) ∙ (C ∙ (B ∙ (W ∙ K)) ∙ Z ∙ Y) [ Q₂ Hp ]
s₂ = ⊢ Q ∙ (C ∙ (B ∙ (W ∙ K)) ∙ Z ∙ X) ∙ (X ∙ Z) [ p₅ ]
s₃ = ⊢ Q ∙ (C ∙ (B ∙ (W ∙ K)) ∙ Z ∙ Y) ∙ (Y ∙ Z) [ p₅ ]
s₄ = ⊢ Q ∙ (X ∙ Z) ∙ (C ∙ (B ∙ (W ∙ K)) ∙ Z ∙ X) [ prop₂ s₂ ]
s₅ = ⊢ Q ∙ (X ∙ Z) ∙ (Y ∙ Z) [ prop₃ s₄ $ prop₃ s₁ s₃ ]
prop₅ : ∀ {X Y} → X ≡ Y → ⊢ Q ∙ X ∙ Y
prop₅ {X} {Y} refl = prop₁
isEquivalence : IsEquivalence _≈_
isEquivalence = record
{ refl = prop₁
; sym = prop₂
; trans = prop₃
}
setoid : Setoid _ _
setoid = record
{ Carrier = Combinator
; _≈_ = _≈_
; isEquivalence = isEquivalence
}
module Reasoning where
module ≈ = IsEquivalence isEquivalence
import Relation.Binary.Reasoning.Base.Single _≈_ ≈.refl ≈.trans as Base
open Base using (begin_; _∎) public
infixr 2 _≈⟨⟩_ step-≈ step-≈˘
_≈⟨⟩_ : ∀ x {y} → x Base.IsRelatedTo y → x Base.IsRelatedTo y
_ ≈⟨⟩ x≈y = x≈y
step-≈ = Base.step-∼
syntax step-≈ x y≈z x≈y = x ≈⟨ x≈y ⟩ y≈z
step-≈˘ : ∀ x {y z} → y Base.IsRelatedTo z → y ≈ x → x Base.IsRelatedTo z
step-≈˘ x y∼z y≈x = x ≈⟨ ≈.sym y≈x ⟩ y∼z
syntax step-≈˘ x y≈z y≈x = x ≈˘⟨ y≈x ⟩ y≈z
cong : Congruent₂ _≈_ _∙_
cong {X} {X′} {Y} {Y′} ⊢X==X′ ⊢Y==Y′ = s₃ where
s₁ = ⊢ X ∙ Y == X ∙ Y′ [ Q₂ ⊢Y==Y′ ]
s₂ = ⊢ X ∙ Y′ == X′ ∙ Y′ [ prop₄ ⊢X==X′ ]
s₃ = ⊢ X ∙ Y == X′ ∙ Y′ [ prop₃ s₁ s₂ ]
congˡ : LeftCongruent _≈_ _∙_
congˡ = Q₂
congʳ : RightCongruent _≈_ _∙_
congʳ = prop₄
prop₉ : ∀ {X} → ⊢ I ∙ X == X
prop₉ {X} = begin
I ∙ X ≈⟨⟩
W ∙ K ∙ X ≈⟨ W ⟩
K ∙ X ∙ X ≈⟨ K ⟩
X ∎
where open Reasoning
S : Combinator
S = B ∙ (B ∙ W) ∙ (B ∙ B ∙ C)
prop-S : ∀ {X} {Y} {Z} → ⊢ S ∙ X ∙ Y ∙ Z == X ∙ Z ∙ (Y ∙ Z)
prop-S {X} {Y} {Z} = begin
S ∙ X ∙ Y ∙ Z ≈⟨⟩
B ∙ (B ∙ W) ∙ (B ∙ B ∙ C) ∙ X ∙ Y ∙ Z ≈⟨ congʳ $ congʳ B ⟩
B ∙ W ∙ (B ∙ B ∙ C ∙ X) ∙ Y ∙ Z ≈⟨ congʳ B ⟩
W ∙ (B ∙ B ∙ C ∙ X ∙ Y) ∙ Z ≈⟨ W ⟩
B ∙ B ∙ C ∙ X ∙ Y ∙ Z ∙ Z ≈⟨ congʳ $ congʳ $ congʳ B ⟩
B ∙ (C ∙ X) ∙ Y ∙ Z ∙ Z ≈⟨ congʳ B ⟩
C ∙ X ∙ (Y ∙ Z) ∙ Z ≈⟨ C ⟩
X ∙ Z ∙ (Y ∙ Z) ∎
where open Reasoning