{-# OPTIONS --exact-split #-}
{-# OPTIONS --no-sized-types #-}
{-# OPTIONS --no-universe-polymorphism #-}
{-# OPTIONS --without-K #-}
module FOTC.Data.Bool.PropertiesI where
open import Common.FOL.Relation.Binary.EqReasoning
open import FOTC.Base
open import FOTC.Data.Bool
open import FOTC.Data.Nat.Inequalities
open import FOTC.Data.Nat.Inequalities.PropertiesI
open import FOTC.Data.Nat.Type
&&-leftCong : ∀ {a b c} → a ≡ b → a && c ≡ b && c
&&-leftCong refl = refl
&&-rightCong : ∀ {a b c} → b ≡ c → a && b ≡ a && c
&&-rightCong refl = refl
&&-cong : ∀ {a b c d } → a ≡ c → b ≡ d → a && b ≡ c && d
&&-cong refl refl = refl
notCong : ∀ {a b} → a ≡ b → not a ≡ not b
notCong refl = refl
t&&x≡x : ∀ b → true && b ≡ b
t&&x≡x b = if-true b
f&&x≡f : ∀ b → false && b ≡ false
f&&x≡f b = if-false false
not-t : not true ≡ false
not-t = if-true false
not-f : not false ≡ true
not-f = if-false true
&&-Bool : ∀ {a b} → Bool a → Bool b → Bool (a && b)
&&-Bool {b = b} btrue Bb = subst Bool (sym (t&&x≡x b)) Bb
&&-Bool {b = b} bfalse Bb = subst Bool (sym (f&&x≡f b)) bfalse
not-Bool : ∀ {b} → Bool b → Bool (not b)
not-Bool btrue = subst Bool (sym not-t) bfalse
not-Bool bfalse = subst Bool (sym not-f) btrue
&&-comm : ∀ {a b} → Bool a → Bool b → a && b ≡ b && a
&&-comm btrue btrue = refl
&&-comm btrue bfalse = trans (t&&x≡x false) (sym (f&&x≡f true))
&&-comm bfalse btrue = trans (f&&x≡f true) (sym (t&&x≡x false))
&&-comm bfalse bfalse = refl
&&-assoc : ∀ {a b c} → Bool a → Bool b → Bool c → (a && b) && c ≡ a && b && c
&&-assoc btrue btrue btrue = &&-cong (t&&x≡x true) (sym (t&&x≡x true))
&&-assoc btrue btrue bfalse = &&-cong (t&&x≡x true) (sym (t&&x≡x false))
&&-assoc btrue bfalse btrue =
(true && false) && true ≡⟨ &&-comm (&&-Bool btrue bfalse) btrue ⟩
true && (true && false) ≡⟨ t&&x≡x (true && false) ⟩
true && false ≡⟨ &&-rightCong (sym (f&&x≡f true)) ⟩
true && false && true ∎
&&-assoc btrue bfalse bfalse =
(true && false) && false ≡⟨ &&-comm (&&-Bool btrue bfalse) bfalse ⟩
false && (true && false) ≡⟨ f&&x≡f (true && false) ⟩
false ≡⟨ sym (f&&x≡f false) ⟩
false && false ≡⟨ sym (t&&x≡x (false && false)) ⟩
true && false && false ∎
&&-assoc bfalse btrue btrue = &&-cong (f&&x≡f true) (sym (t&&x≡x true))
&&-assoc bfalse btrue bfalse = &&-cong (f&&x≡f true) (sym (t&&x≡x false))
&&-assoc bfalse bfalse btrue =
(false && false) && true ≡⟨ &&-comm (&&-Bool bfalse bfalse) btrue ⟩
true && (false && false) ≡⟨ t&&x≡x (false && false) ⟩
false && false ≡⟨ f&&x≡f false ⟩
false ≡⟨ sym (f&&x≡f (false && true)) ⟩
false && false && true ∎
&&-assoc bfalse bfalse bfalse = &&-cong (f&&x≡f false) (sym (f&&x≡f false))
&&-list₂-t : ∀ {a b} → Bool a → Bool b → a && b ≡ true → a ≡ true ∧ b ≡ true
&&-list₂-t btrue btrue h = refl , refl
&&-list₂-t btrue bfalse h = ⊥-elim (t≢f (trans (sym h) (t&&x≡x false)))
&&-list₂-t bfalse btrue h = ⊥-elim (t≢f (trans (sym h) (f&&x≡f true)))
&&-list₂-t bfalse bfalse h = ⊥-elim (t≢f (trans (sym h) (f&&x≡f false)))
&&-list₂-t₁ : ∀ {a b} → Bool a → Bool b → a && b ≡ true → a ≡ true
&&-list₂-t₁ Ba Bb h = ∧-proj₁ (&&-list₂-t Ba Bb h)
&&-list₂-t₂ : ∀ {a b} → Bool a → Bool b → a && b ≡ true → b ≡ true
&&-list₂-t₂ Ba Bb h = ∧-proj₂ (&&-list₂-t Ba Bb h)
&&-list₂-all-t : ∀ {a b} → Bool a → Bool b →
(a ≡ true ∧ b ≡ true) →
a && b ≡ true
&&-list₂-all-t btrue btrue h = t&&x≡x true
&&-list₂-all-t btrue bfalse (h₁ , h₂) = ⊥-elim (t≢f (sym h₂))
&&-list₂-all-t bfalse Bb (h₁ , h₂) = ⊥-elim (t≢f (sym h₁))
&&-list₃-all-t : ∀ {a b c} → Bool a → Bool b → Bool c →
a ≡ true ∧ b ≡ true ∧ c ≡ true →
a && b && c ≡ true
&&-list₃-all-t btrue btrue btrue h = trans (t&&x≡x (true && true)) (t&&x≡x true)
&&-list₃-all-t btrue btrue bfalse (h₁ , h₂ , h₃) = ⊥-elim (t≢f (sym h₃))
&&-list₃-all-t btrue bfalse Bc (h₁ , h₂ , h₃) = ⊥-elim (t≢f (sym h₂))
&&-list₃-all-t bfalse Bb Bc (h₁ , h₂ , h₃) = ⊥-elim (t≢f (sym h₁))
&&-list₄-all-t : ∀ {a b c d} → Bool a → Bool b → Bool c → Bool d →
a ≡ true ∧ b ≡ true ∧ c ≡ true ∧ d ≡ true →
a && b && c && d ≡ true
&&-list₄-all-t btrue btrue btrue btrue h =
trans₂ (t&&x≡x (true && true && true)) (t&&x≡x (true && true)) (t&&x≡x true)
&&-list₄-all-t btrue btrue btrue bfalse (h₁ , h₂ , h₃ , h₄) = ⊥-elim (t≢f (sym h₄))
&&-list₄-all-t btrue btrue bfalse Bd (h₁ , h₂ , h₃ , h₄) = ⊥-elim (t≢f (sym h₃))
&&-list₄-all-t btrue bfalse Bc Bd (h₁ , h₂ , h₃ , h₄) = ⊥-elim (t≢f (sym h₂))
&&-list₄-all-t bfalse Bb Bc Bd (h₁ , h₂ , h₃ , h₄) = ⊥-elim (t≢f (sym h₁))
&&-list₄-some-f : ∀ {a b c d} → Bool a → Bool b → Bool c → Bool d →
a ≡ false ∨ b ≡ false ∨ c ≡ false ∨ d ≡ false →
a && b && c && d ≡ false
&&-list₄-some-f btrue Bb Bc Bd (inj₁ h) = ⊥-elim (t≢f h)
&&-list₄-some-f btrue btrue Bc Bd (inj₂ (inj₁ h)) = ⊥-elim (t≢f h)
&&-list₄-some-f btrue btrue btrue Bd (inj₂ (inj₂ (inj₁ h))) = ⊥-elim (t≢f h)
&&-list₄-some-f btrue btrue btrue btrue (inj₂ (inj₂ (inj₂ h))) = ⊥-elim (t≢f h)
&&-list₄-some-f btrue btrue btrue bfalse (inj₂ (inj₂ (inj₂ h))) =
trans (t&&x≡x (true && true && false))
(trans (t&&x≡x (true && false)) (t&&x≡x false))
&&-list₄-some-f btrue btrue bfalse btrue (inj₂ (inj₂ (inj₁ h))) =
trans (t&&x≡x (true && false && true))
(trans (t&&x≡x (false && true)) (f&&x≡f true))
&&-list₄-some-f btrue btrue bfalse btrue (inj₂ (inj₂ (inj₂ h))) = ⊥-elim (t≢f h)
&&-list₄-some-f btrue btrue bfalse bfalse (inj₂ (inj₂ h)) =
trans (t&&x≡x (true && false && false))
(trans (t&&x≡x (false && false)) (f&&x≡f false))
&&-list₄-some-f {c = c} {d} btrue bfalse Bc Bd (inj₂ h) =
trans (t&&x≡x (false && c && d)) (f&&x≡f (c && d))
&&-list₄-some-f {b = b} {c} {d} bfalse Bb Bc Bd _ = f&&x≡f (b && c && d)
&&-list₄-t : ∀ {a b c d} → Bool a → Bool b → Bool c → Bool d →
a && b && c && d ≡ true →
a ≡ true ∧ b ≡ true ∧ c ≡ true ∧ d ≡ true
&&-list₄-t btrue btrue btrue btrue h = refl , refl , refl , refl
&&-list₄-t btrue btrue btrue bfalse h =
⊥-elim (t≢f
(trans (sym h)
(&&-list₄-some-f btrue btrue btrue bfalse (inj₂ (inj₂ (inj₂ refl))))))
&&-list₄-t btrue btrue bfalse Bd h =
⊥-elim (t≢f
(trans (sym h)
(&&-list₄-some-f btrue btrue bfalse Bd (inj₂ (inj₂ (inj₁ refl))))))
&&-list₄-t btrue bfalse Bc Bd h =
⊥-elim (t≢f
(trans (sym h) (&&-list₄-some-f btrue bfalse Bc Bd (inj₂ (inj₁ refl)))))
&&-list₄-t bfalse Bb Bc Bd h =
⊥-elim (t≢f (trans (sym h) (&&-list₄-some-f bfalse Bb Bc Bd (inj₁ refl))))
&&-list₄-t₁ : ∀ {a b c d} → Bool a → Bool b → Bool c → Bool d →
a && b && c && d ≡ true → a ≡ true
&&-list₄-t₁ Ba Bb Bc Bd h = ∧-proj₁ (&&-list₄-t Ba Bb Bc Bd h)
&&-list₄-t₂ : ∀ {a b c d} → Bool a → Bool b → Bool c → Bool d →
a && b && c && d ≡ true → b ≡ true
&&-list₄-t₂ Ba Bb Bc Bd h = ∧-proj₁ (∧-proj₂ (&&-list₄-t Ba Bb Bc Bd h))
&&-list₄-t₃ : ∀ {a b c d} → Bool a → Bool b → Bool c → Bool d →
a && b && c && d ≡ true → c ≡ true
&&-list₄-t₃ Ba Bb Bc Bd h =
∧-proj₁ (∧-proj₂ (∧-proj₂ (&&-list₄-t Ba Bb Bc Bd h)))
&&-list₄-t₄ : ∀ {a b c d} → Bool a → Bool b → Bool c → Bool d →
a && b && c && d ≡ true → d ≡ true
&&-list₄-t₄ Ba Bb Bc Bd h =
∧-proj₂ (∧-proj₂ (∧-proj₂ (&&-list₄-t Ba Bb Bc Bd h)))
x≢not-x : ∀ {b} → Bool b → b ≢ not b
x≢not-x btrue h = t≢f (trans h not-t)
x≢not-x bfalse h = t≢f (sym (trans h not-f))
not-x≢x : ∀ {b} → Bool b → not b ≢ b
not-x≢x Bb h = x≢not-x Bb (sym h)
not-involutive : ∀ {b} → Bool b → not (not b) ≡ b
not-involutive btrue = trans (notCong not-t) not-f
not-involutive bfalse = trans (notCong not-f) not-t
lt-Bool : ∀ {m n} → N m → N n → Bool (lt m n)
lt-Bool nzero nzero = subst Bool (sym lt-00) bfalse
lt-Bool nzero (nsucc {n} Nn) = subst Bool (sym (lt-0S n)) btrue
lt-Bool (nsucc {m} Nm) nzero = subst Bool (sym (lt-S0 m)) bfalse
lt-Bool (nsucc {m} Nm) (nsucc {n} Nn) = subst Bool (sym (lt-SS m n)) (lt-Bool Nm Nn)
le-Bool : ∀ {m n} → N m → N n → Bool (le m n)
le-Bool {n = n} nzero Nn = subst Bool (sym (lt-0S n)) btrue
le-Bool (nsucc Nm) nzero = subst Bool (sym (Sx≰0 Nm)) bfalse
le-Bool (nsucc {m} Nm) (nsucc {n} Nn) =
subst Bool (sym (lt-SS m (succ₁ n))) (le-Bool Nm Nn)