{-# OPTIONS --cubical-compatible --safe #-}
open import Algebra.Bundles
using (BooleanSemiring; BooleanRing
; CommutativeMonoid; IdempotentCommutativeMonoid
; Ring; CommutativeRing)
module Algebra.Properties.BooleanSemiring
{c ℓ} (booleanSemiring : BooleanSemiring c ℓ) where
open import Algebra.Core using (Op₁; Op₂)
open import Algebra.Lattice.Bundles
using (DistributiveLattice; BooleanAlgebra)
import Algebra.Properties.CommutativeMonoid as CommutativeMonoidProperties
import Algebra.Properties.IdempotentCommutativeMonoid as IdempotentCommutativeMonoidProperties
import Algebra.Lattice.Properties.DistributiveLattice as DistributiveLatticeProperties
open import Data.Product.Base using (_,_)
open import Function.Base using (id; _∘_; _$_)
open BooleanSemiring booleanSemiring
import Algebra.Consequences.Setoid setoid as Consequences
open import Algebra.Definitions _≈_
open import Algebra.Lattice.Structures.Biased _≈_
using (IsLattice₂; isLattice₂
; IsDistributiveLatticeʳʲᵐ; isDistributiveLatticeʳʲᵐ
; IsBooleanAlgebraʳ; isBooleanAlgebraʳ
)
open import Algebra.Lattice.Structures _≈_
using (IsLattice; IsDistributiveLattice; IsBooleanAlgebra)
open import Algebra.Structures _≈_
using (IsMagma; IsSemigroup; IsBand
; IsCommutativeMonoid; IsIdempotentCommutativeMonoid
; IsGroup; IsAbelianGroup
; IsRing; IsCommutativeRing; IsBooleanRing
)
open import Relation.Binary.Reasoning.Setoid setoid
open import Algebra.Properties.Semiring semiring public
xy+yx≈0 : ∀ x y → x * y + y * x ≈ 0#
xy+yx≈0 x y = +-cancelˡ (x * x) _ _ $ +-cancelʳ (y * y) _ _ $ begin
x * x + ((x * y) + (y * x)) + y * y ≈⟨ +-congʳ (+-assoc _ _ _) ⟨
x * x + x * y + y * x + y * y ≈⟨ binomial-expansion x y x y ⟨
(x + y) * (x + y) ≈⟨ *-idem (x + y) ⟩
x + y ≈⟨ +-congˡ (*-idem y) ⟨
x + y * y ≈⟨ +-congʳ (*-idem x) ⟨
x * x + y * y ≈⟨ +-congʳ (+-identityʳ (x * x)) ⟨
x * x + 0# + y * y ∎
y≈x⇒x+y≈0 : ∀ {x y} → y ≈ x → x + y ≈ 0#
y≈x⇒x+y≈0 {x = x} {y = y} y≈x = begin
x + y ≈⟨ +-cong (*-idem x) (*-idem y) ⟨
x * x + y * y ≈⟨ +-cong (*-congˡ (sym y≈x)) (*-congˡ y≈x) ⟩
x * y + y * x ≈⟨ xy+yx≈0 x y ⟩
0# ∎
x+x≈0 : ∀ x → x + x ≈ 0#
x+x≈0 x = y≈x⇒x+y≈0 refl
x+y≈0⇒y≈x : ∀ {x y} → x + y ≈ 0# → y ≈ x
x+y≈0⇒y≈x {x = x} {y = y} x+y≈0 = +-cancelˡ x _ _ $ begin
x + y ≈⟨ x+y≈0 ⟩
0# ≈⟨ x+x≈0 x ⟨
x + x ∎
*-comm : Commutative _*_
*-comm x y = +-cancelʳ (y * x) _ _ $ begin
x * y + y * x ≈⟨ xy+yx≈0 x y ⟩
0# ≈⟨ x+x≈0 (y * x) ⟨
y * x + y * x ∎
+-isGroup : IsGroup _+_ 0# id
+-isGroup = record { isMonoid = +-isMonoid ; inverse = x+x≈0 , x+x≈0 ; ⁻¹-cong = id }
+-isAbelianGroup : IsAbelianGroup _+_ 0# id
+-isAbelianGroup = record { isGroup = +-isGroup ; comm = +-comm }
*-isCommutativeMonoid : IsCommutativeMonoid _*_ 1#
*-isCommutativeMonoid = record { isMonoid = *-isMonoid ; comm = *-comm }
*-isIdempotentCommutativeMonoid : IsIdempotentCommutativeMonoid _*_ 1#
*-isIdempotentCommutativeMonoid = record
{ isCommutativeMonoid = *-isCommutativeMonoid
; idem = *-idem
}
open IsIdempotentCommutativeMonoid *-isIdempotentCommutativeMonoid public
using () renaming (isCommutativeBand to *-isCommutativeBand)
isRing : IsRing _+_ _*_ id 0# 1#
isRing = record
{ +-isAbelianGroup = +-isAbelianGroup
; *-cong = *-cong
; *-assoc = *-assoc
; *-identity = *-identity
; distrib = distrib
}
isCommutativeRing : IsCommutativeRing _+_ _*_ id 0# 1#
isCommutativeRing = record { isRing = isRing ; *-comm = *-comm }
isBooleanRing : IsBooleanRing _+_ _*_ id 0# 1#
isBooleanRing = record { isCommutativeRing = isCommutativeRing ; *-idem = *-idem }
*-commutativeMonoid : CommutativeMonoid _ _
*-commutativeMonoid = record { isCommutativeMonoid = *-isCommutativeMonoid }
*-idempotentCommutativeMonoid : IdempotentCommutativeMonoid _ _
*-idempotentCommutativeMonoid = record
{ isIdempotentCommutativeMonoid = *-isIdempotentCommutativeMonoid }
open IdempotentCommutativeMonoid *-idempotentCommutativeMonoid public
using () renaming (commutativeBand to *-commutativeBand)
commutativeRing : CommutativeRing _ _
commutativeRing = record { isCommutativeRing = isCommutativeRing }
open CommutativeRing commutativeRing public
using (ring)
booleanRing : BooleanRing _ _
booleanRing = record { isBooleanRing = isBooleanRing }
infix 8 ¬_
¬_ : Op₁ Carrier
¬ x = 1# + x
¬-cong : Congruent₁ ¬_
¬-cong = +-congˡ
¬-involutive : Involutive ¬_
¬-involutive x = begin
¬ ¬ x ≡⟨⟩
1# + (1# + x) ≈⟨ +-assoc 1# 1# x ⟨
1# + 1# + x ≈⟨ +-congʳ (x+x≈0 1#) ⟩
0# + x ≈⟨ +-identityˡ x ⟩
x ∎
∧-complementʳ : RightInverse 0# ¬_ _*_
∧-complementʳ x = begin
x * (¬ x) ≈⟨ distribˡ x 1# x ⟩
x * 1# + x * x ≈⟨ +-cong (*-identityʳ x) (*-idem x) ⟩
x + x ≈⟨ x+x≈0 x ⟩
0# ∎
private
*-lemma : ∀ x y → x + (x * ¬ x) * y ≈ x
*-lemma x y = begin
x + (x * ¬ x) * y ≈⟨ +-congˡ (*-congʳ (∧-complementʳ x)) ⟩
x + 0# * y ≈⟨ +-congˡ (zeroˡ y) ⟩
x + 0# ≈⟨ +-identityʳ _ ⟩
x ∎
infixr 6 _∨_
_∨_ : Op₂ Carrier
x ∨ y = x + y * ¬ x
∨-complementʳ : RightInverse 1# ¬_ _∨_
∨-complementʳ x = begin
x ∨ ¬ x ≈⟨ +-congˡ (*-idem (¬ x)) ⟩
x + ¬ x ≈⟨ x∙yz≈y∙xz x 1# x ⟩
1# + (x + x) ≈⟨ +-congˡ (x+x≈0 x) ⟩
1# + 0# ≈⟨ +-identityʳ _ ⟩
1# ∎
where open CommutativeMonoidProperties +-commutativeMonoid
∨-def : ∀ x y → x ∨ y ≈ x + y + x * y
∨-def x y = begin
x ∨ y ≈⟨ +-congˡ (distribˡ y 1# x) ⟩
x + (y * 1# + y * x) ≈⟨ +-assoc x (y * 1#) (y * x) ⟨
x + y * 1# + y * x ≈⟨ +-cong (+-congˡ (*-identityʳ y)) (*-comm y x) ⟩
x + y + x * y ∎
∨-cong : Congruent₂ _∨_
∨-cong x≈x′ y≈y′ = +-cong x≈x′ (*-cong y≈y′ (¬-cong x≈x′))
∨-comm : Commutative _∨_
∨-comm x y = begin
x ∨ y ≈⟨ ∨-def x y ⟩
x + y + x * y ≈⟨ +-cong (+-comm x y) (*-comm x y) ⟩
y + x + y * x ≈⟨ ∨-def y x ⟨
y ∨ x ∎
∨-idem : Idempotent _∨_
∨-idem x = begin
x ∨ x ≈⟨ +-congˡ (∧-complementʳ x) ⟩
x + 0# ≈⟨ +-identityʳ x ⟩
x ∎
deMorgan₁ : ∀ x y → ¬ (x * y) ≈ ¬ x ∨ ¬ y
deMorgan₁ x y = begin
¬ (x * y) ≡⟨⟩
1# + x * y ≈⟨ +-cong (+-identityʳ 1#) (*-comm y x) ⟨
1# + 0# + y * x ≈⟨ +-congʳ (+-congˡ (x+x≈0 x)) ⟨
1# + (x + x) + y * x ≈⟨ +-congʳ (+-assoc 1# x x) ⟨
1# + x + x + y * x ≈⟨ +-congʳ (+-congˡ (*-identityˡ x)) ⟨
1# + x + 1# * x + y * x ≈⟨ +-assoc (1# + x) (1# * x) (y * x) ⟩
1# + x + (1# * x + y * x) ≈⟨ +-congˡ (distribʳ x 1# y) ⟨
1# + x + ¬ y * x ≈⟨ +-congˡ (*-congˡ (¬-involutive x)) ⟨
¬ x + ¬ y * ¬ ¬ x ≡⟨⟩
¬ x ∨ ¬ y ∎
deMorgan₂ : ∀ x y → ¬ (x ∨ y) ≈ ¬ x * ¬ y
deMorgan₂ x y = begin
¬ (x ∨ y) ≈⟨ +-congˡ (∨-def x y) ⟩
1# + (x + y + x * y) ≈⟨ +-assoc _ _ _ ⟨
1# + (x + y) + x * y ≈⟨ +-congʳ (x∙yz≈xz∙y 1# x y) ⟩
1# + y + x + x * y ≈⟨ +-congʳ (+-cong (+-cong (*-idem _) (*-identityˡ y)) (*-identityʳ x)) ⟨
1# * 1# + 1# * y + x * 1# + x * y ≈⟨ binomial-expansion 1# x 1# y ⟨
(1# + x) * (1# + y) ≡⟨⟩
¬ x * ¬ y ∎
where open CommutativeMonoidProperties +-commutativeMonoid
∨-assoc : Associative _∨_
∨-assoc x y z = begin
(x ∨ y) ∨ z ≈⟨ ¬-involutive ((x ∨ y) ∨ z) ⟨
¬ ¬ ((x ∨ y) ∨ z) ≈⟨ ¬-cong (deMorgan₂ (x ∨ y) z) ⟩
¬ (¬ (x ∨ y) * ¬ z) ≈⟨ ¬-cong (*-congʳ (deMorgan₂ x y)) ⟩
¬ ((¬ x * ¬ y) * ¬ z) ≈⟨ ¬-cong (*-assoc (¬ x) (¬ y) (¬ z)) ⟩
¬ (¬ x * (¬ y * ¬ z)) ≈⟨ ¬-cong (*-congˡ (deMorgan₂ y z)) ⟨
¬ (¬ x * ¬ (y ∨ z)) ≈⟨ ¬-cong (deMorgan₂ x (y ∨ z)) ⟨
¬ ¬ (x ∨ y ∨ z) ≈⟨ ¬-involutive (x ∨ y ∨ z) ⟩
x ∨ y ∨ z ∎
∨-absorbs-* : _∨_ Absorbs _*_
∨-absorbs-* x y = begin
x ∨ x * y ≈⟨ +-congˡ (xy∙z≈xz∙y x y (¬ x)) ⟩
x + (x * ¬ x) * y ≈⟨ *-lemma x y ⟩
x ∎
where open CommutativeMonoidProperties *-commutativeMonoid
*-absorbs-∨ : _*_ Absorbs _∨_
*-absorbs-∨ x y = begin
x * (x ∨ y) ≈⟨ distribˡ x x (y * ¬ x) ⟩
x * x + x * (y * ¬ x) ≈⟨ +-cong (*-idem x) (x∙yz≈xz∙y x y (¬ x)) ⟩
x + (x * ¬ x) * y ≈⟨ *-lemma x y ⟩
x ∎
where open CommutativeMonoidProperties *-commutativeMonoid
*-distribʳ-∨ : _*_ DistributesOverʳ _∨_
*-distribʳ-∨ x y z = begin
(y ∨ z) * x ≈⟨ *-congʳ (∨-def y z) ⟩
(y + z + y * z) * x ≈⟨ distribʳ x (y + z) (y * z) ⟩
((y + z) * x + y * z * x) ≈⟨ +-cong (distribʳ x y z) (∙-distrʳ-∙ x y z) ⟩
(y * x + z * x) + (y * x) * (z * x) ≈⟨ ∨-def (y * x) (z * x) ⟨
(y * x) ∨ (z * x) ∎
where open IdempotentCommutativeMonoidProperties *-idempotentCommutativeMonoid
∨-isMagma : IsMagma _∨_
∨-isMagma = record { isEquivalence = isEquivalence ; ∙-cong = ∨-cong }
∨-isSemigroup : IsSemigroup _∨_
∨-isSemigroup = record { isMagma = ∨-isMagma ; assoc = ∨-assoc }
∨-isBand : IsBand _∨_
∨-isBand = record { isSemigroup = ∨-isSemigroup ; idem = ∨-idem }
*-∨-isLattice : IsLattice _*_ _∨_
*-∨-isLattice = isLattice₂ $ record
{ isJoinSemilattice = record { isBand = *-isBand ; comm = *-comm }
; isMeetSemilattice = record { isBand = ∨-isBand ; comm = ∨-comm }
; absorptive = *-absorbs-∨ , ∨-absorbs-*
}
*-∨-isDistributiveLattice : IsDistributiveLattice _*_ _∨_
*-∨-isDistributiveLattice = isDistributiveLatticeʳʲᵐ $ record
{ isLattice = *-∨-isLattice
; ∨-distribʳ-∧ = *-distribʳ-∨
}
*-∨-distributiveLattice : DistributiveLattice _ _
*-∨-distributiveLattice = record { isDistributiveLattice = *-∨-isDistributiveLattice }
isDistributiveLattice : IsDistributiveLattice _∨_ _*_
isDistributiveLattice =
DistributiveLatticeProperties.∧-∨-isDistributiveLattice *-∨-distributiveLattice
isBooleanAlgebra : IsBooleanAlgebra _∨_ _*_ ¬_ 1# 0#
isBooleanAlgebra = isBooleanAlgebraʳ $ record
{ isDistributiveLattice = isDistributiveLattice
; ∨-complementʳ = ∨-complementʳ
; ∧-complementʳ = ∧-complementʳ
; ¬-cong = ¬-cong
}
booleanAlgebra : BooleanAlgebra _ _
booleanAlgebra = record { isBooleanAlgebra = isBooleanAlgebra }