open import Library
module _
(decA : DecSetoid lzero lzero)
(open DecSetoid decA using (_≟_) renaming (Carrier to A)) where
infix 1 _≅⟨_⟩≅_
infixl 4 _∪_
infixl 6 _·_
infixr 15 _*
record Lang i : Set where
coinductive
field
ν : Bool
δ : ∀{j : Size< i} → A → Lang j
open Lang
∅ : ∀{i} → Lang i
ν ∅ = false
δ ∅ a = ∅
ε : ∀{i} → Lang i
ν ε = true
δ ε a = ∅
_∪_ : ∀{i} (k l : Lang i) → Lang i
ν (k ∪ l) = ν k ∨ ν l
δ (k ∪ l) a = δ k a ∪ δ l a
_·_ : ∀{i} (k l : Lang i) → Lang i
ν (k · l) = ν k ∧ ν l
δ (k · l) a = if ν k then (δ k a · l) ∪ δ l a else (δ k a · l)
_* : ∀{i} (l : Lang i) → Lang i
ν (l *) = true
δ (l *) a = δ l a · (l *)
record _≅⟨_⟩≅_ (l : Lang ∞) i (k : Lang ∞) : Set where
coinductive
field
≅ν : ν l ≡ ν k
≅δ : ∀{j : Size< i} (a : A) → δ l a ≅⟨ j ⟩≅ δ k a
open _≅⟨_⟩≅_ public
≅refl : ∀{i} {l : Lang ∞} → l ≅⟨ i ⟩≅ l
≅ν ≅refl = refl
≅δ ≅refl a = ≅refl
≅sym : ∀{i} {k l : Lang ∞} (p : l ≅⟨ i ⟩≅ k) → k ≅⟨ i ⟩≅ l
≅ν (≅sym p) = sym (≅ν p)
≅δ (≅sym p) a = ≅sym (≅δ p a)
≅trans : ∀{i} {k l m : Lang ∞} (p : k ≅⟨ i ⟩≅ l) (q : l ≅⟨ i ⟩≅ m) → k ≅⟨ i ⟩≅ m
≅ν (≅trans p q) = trans (≅ν p) (≅ν q)
≅δ (≅trans p q) a = ≅trans (≅δ p a) (≅δ q a)
≅isEquivalence : (i : Size) → IsEquivalence (λ l l' → l ≅⟨ i ⟩≅ l')
IsEquivalence.refl (≅isEquivalence i) = ≅refl
IsEquivalence.sym (≅isEquivalence i) = ≅sym
IsEquivalence.trans (≅isEquivalence i) = ≅trans
Bis : ∀(i : Size) → Setoid lzero lzero
Setoid.Carrier (Bis i) = Lang ∞
Setoid._≈_ (Bis i) = λ l k → l ≅⟨ i ⟩≅ k
Setoid.isEquivalence (Bis i) = ≅isEquivalence i
union-assoc : ∀{i} (k {l m} : Lang ∞) → (k ∪ l) ∪ m ≅⟨ i ⟩≅ k ∪ (l ∪ m)
≅ν (union-assoc k) = ∨-assoc (ν k) _ _
≅δ (union-assoc k) a = union-assoc _
union-comm : ∀{i} (l k : Lang ∞) → l ∪ k ≅⟨ i ⟩≅ k ∪ l
≅ν (union-comm l k) = ∨-comm (ν l) _
≅δ (union-comm l k) a = union-comm (δ l a) (δ k a)
union-idem : ∀{i} {l : Lang ∞} → l ∪ l ≅⟨ i ⟩≅ l
≅ν union-idem = ∨-idempotent _
≅δ union-idem a = union-idem
union-empty : ∀{i} {l : Lang ∞} → ∅ ∪ l ≅⟨ i ⟩≅ l
≅ν union-empty = refl
≅δ union-empty a = union-empty
union-congˡ : ∀{i}{m l k : Lang ∞} (p : l ≅⟨ i ⟩≅ k) → l ∪ m ≅⟨ i ⟩≅ k ∪ m
≅ν (union-congˡ p) rewrite ≅ν p = refl
≅δ (union-congˡ p) a = union-congˡ (≅δ p a)
union-congʳ : ∀{i}{m l k : Lang ∞} (p : l ≅⟨ i ⟩≅ k) → m ∪ l ≅⟨ i ⟩≅ m ∪ l
≅ν (union-congʳ p) rewrite ≅ν p = refl
≅δ (union-congʳ p) a = union-congʳ (≅δ p a)
union-cong : ∀{i}{k k' l l' : Lang ∞} (p : k ≅⟨ i ⟩≅ k') (q : l ≅⟨ i ⟩≅ l') → k ∪ l ≅⟨ i ⟩≅ k' ∪ l'
≅ν (union-cong p q) rewrite ≅ν p | ≅ν q = refl
≅δ (union-cong p q) a = union-cong (≅δ p a) (≅δ q a)
union-icm : (i : Size) → IdempotentCommutativeMonoid _ _
union-icm i = record
{ Carrier = Lang ∞
; _≈_ = λ l l' → l ≅⟨ i ⟩≅ l'
; _∙_ = _∪_
; ε = ∅
; isIdempotentCommutativeMonoid = record
{ isCommutativeMonoid = record
{ isSemigroup = record
{ isEquivalence = ≅isEquivalence i
; assoc = λ x y z → union-assoc x
; ∙-cong = union-cong
}
; identityˡ = λ l → union-empty
; comm = union-comm
}
; idem = λ l → union-idem
}
}
union-swap23 : ∀{i} (k {l m} : Lang ∞) →
(k ∪ l) ∪ m ≅⟨ i ⟩≅ (k ∪ m) ∪ l
union-swap23 {i} k {l} {m} = prove 3 ((x ⊕ y) ⊕ z) ((x ⊕ z) ⊕ y) (k ∷ l ∷ m ∷ [])
where
open ICMSolver (union-icm i)
x = var zero
y = var (suc zero)
z = var (suc (suc zero))
union-swap24 : ∀{i} {k l m n : Lang ∞} →
(k ∪ l) ∪ (m ∪ n) ≅⟨ i ⟩≅ (k ∪ m) ∪ (l ∪ n)
union-swap24 {i} {k} {l} {m} {n} = prove 4 ((x ⊕ y) ⊕ (z ⊕ u)) ((x ⊕ z) ⊕ (y ⊕ u)) (k ∷ l ∷ m ∷ n ∷ [])
where
open ICMSolver (union-icm i)
x = var zero
y = var (suc zero)
z = var (suc (suc zero))
u = var (suc (suc (suc zero)))
union-union-distr : ∀{i} (k {l m} : Lang ∞) →
(k ∪ l) ∪ m ≅⟨ i ⟩≅ (k ∪ m) ∪ (l ∪ m)
union-union-distr {i} k {l} {m} = prove 3 ((x ⊕ y) ⊕ z) ((x ⊕ z) ⊕ (y ⊕ z)) (k ∷ l ∷ m ∷ [])
where
open ICMSolver (union-icm i)
x = var zero
y = var (suc zero)
z = var (suc (suc zero))
concat-union-distribˡ : ∀{i} (k {l m} : Lang ∞) → (k ∪ l) · m ≅⟨ i ⟩≅ (k · m) ∪ (l · m)
≅ν (concat-union-distribˡ k) = ∧-∨-distribʳ _ (ν k) _
≅δ (concat-union-distribˡ k {l} {m}) a with ν k | ν l
... | true | true = begin
(δ k a ∪ δ l a) · m ∪ δ m a
≈⟨ union-congˡ (concat-union-distribˡ (δ k a)) ⟩
(δ k a · m ∪ δ l a · m) ∪ δ m a
≈⟨ union-union-distr _ ⟩
(δ k a · m ∪ δ m a) ∪ (δ l a · m ∪ δ m a)
∎
where open EqR (Bis _)
... | true | false = begin
(δ k a ∪ δ l a) · m ∪ δ m a
≈⟨ union-congˡ (concat-union-distribˡ (δ k a)) ⟩
(δ k a · m ∪ δ l a · m) ∪ δ m a
≈⟨ union-swap23 _ ⟩
δ k a · m ∪ δ m a ∪ δ l a · m
∎
where open EqR (Bis _)
... | false | true = begin
(δ k a ∪ δ l a) · m ∪ δ m a
≈⟨ union-congˡ (concat-union-distribˡ (δ k a)) ⟩
(δ k a · m ∪ δ l a · m) ∪ δ m a
≈⟨ union-assoc _ ⟩
δ k a · m ∪ (δ l a · m ∪ δ m a)
∎
where open EqR (Bis _)
... | false | false = concat-union-distribˡ (δ k a)
concat-union-distribʳ : ∀{i} (k {l m} : Lang ∞) → k · (l ∪ m) ≅⟨ i ⟩≅ (k · l) ∪ (k · m)
≅ν (concat-union-distribʳ k) = ∧-∨-distribˡ (ν k) _ _
≅δ (concat-union-distribʳ k) a with ν k
≅δ (concat-union-distribʳ k {l} {m}) a | true = begin
δ k a · (l ∪ m) ∪ (δ l a ∪ δ m a)
≈⟨ union-congˡ (concat-union-distribʳ (δ k a)) ⟩
(δ k a · l ∪ δ k a · m) ∪ (δ l a ∪ δ m a)
≈⟨ union-swap24 ⟩
(δ k a · l ∪ δ l a) ∪ (δ k a · m ∪ δ m a)
∎
where open EqR (Bis _)
≅δ (concat-union-distribʳ k) a | false = concat-union-distribʳ (δ k a)
concat-assoc : ∀{i} (k {l m} : Lang ∞) → (k · l) · m ≅⟨ i ⟩≅ k · (l · m)
≅ν (concat-assoc k) = ∧-assoc (ν k) _ _
≅δ (concat-assoc k) a with ν k
≅δ (concat-assoc k ) a | false = concat-assoc (δ k a)
≅δ (concat-assoc k {l} {m}) a | true with ν l
... | true = begin
(δ k a · l ∪ δ l a) · m ∪ δ m a
≈⟨ union-congˡ (concat-union-distribˡ _) ⟩
((δ k a · l) · m ∪ δ l a · m) ∪ δ m a
≈⟨ union-assoc _ ⟩
(δ k a · l) · m ∪ (δ l a · m ∪ δ m a)
≈⟨ union-congˡ (concat-assoc (δ k a)) ⟩
δ k a · (l · m) ∪ (δ l a · m ∪ δ m a)
∎
where open EqR (Bis _)
... | false = begin
(δ k a · l ∪ δ l a) · m
≈⟨ concat-union-distribˡ _ ⟩
(δ k a · l) · m ∪ δ l a · m
≈⟨ union-congˡ (concat-assoc (δ k a)) ⟩
δ k a · (l · m) ∪ δ l a · m
∎
where open EqR (Bis _)
star-rec : ∀{i} (l : Lang ∞) → l * ≅⟨ i ⟩≅ ε ∪ (l · l *)
≅ν (star-rec l) = refl
≅δ (star-rec l) a with ν l
... | true = begin
δ l a · l * ≈⟨ ≅sym union-idem ⟩
(δ l a · l * ∪ δ l a · l *) ≈⟨ ≅sym union-empty ⟩
∅ ∪ (δ l a · l * ∪ δ l a · l *) ∎
where open EqR (Bis _)
... | false = ≅sym union-empty