-
Notifications
You must be signed in to change notification settings - Fork 268
Expand file tree
/
Copy pathNormal.agda
More file actions
145 lines (109 loc) · 4.52 KB
/
Normal.agda
File metadata and controls
145 lines (109 loc) · 4.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
------------------------------------------------------------------------
-- The Agda standard library
--
-- Normal forms in commutative monoids
--
-- Adapted from Algebra.Solver.Monoid.Normal
------------------------------------------------------------------------
{-# OPTIONS --cubical-compatible --safe #-}
open import Algebra.Bundles using (CommutativeMonoid)
module Algebra.Solver.CommutativeMonoid.Normal
{c ℓ} (M : CommutativeMonoid c ℓ) where
open import Algebra.Bundles.Raw using (RawMonoid)
import Algebra.Properties.CommutativeSemigroup as CommutativeSemigroupProperties
import Algebra.Properties.Monoid.Mult as MonoidMultProperties
open import Data.Fin.Base using (Fin; zero; suc)
open import Data.Nat as ℕ using (ℕ; zero; suc; _+_)
open import Data.Vec.Base using (Vec; []; _∷_; lookup; replicate; zipWith)
open import Data.Vec.Relation.Binary.Equality.DecPropositional using (_≡?_)
open import Relation.Binary.Definitions using (DecidableEquality)
open import Relation.Binary.PropositionalEquality as ≡ using (_≡_)
import Relation.Binary.Reasoning.Setoid as ≈-Reasoning
open CommutativeMonoid M
open MonoidMultProperties monoid using (_×_; ×-homo-1; ×-homo-+)
open CommutativeSemigroupProperties commutativeSemigroup using (interchange)
open ≈-Reasoning setoid
private
variable
n : ℕ
------------------------------------------------------------------------
-- Monoid expressions
open import Algebra.Solver.Monoid.Expression monoid public
------------------------------------------------------------------------
-- Normal forms
-- A normal form is a vector of multiplicities (a bag).
private
N : ℕ → Set
N n = Vec ℕ n
-- Constructions on normal forms
-- The empty bag.
empty : N n
empty = replicate _ 0
-- A singleton bag.
sg : (i : Fin n) → N n
sg zero = 1 ∷ empty
sg (suc i) = 0 ∷ sg i
-- The composition of normal forms: bag union.
infixr 10 _•_
_•_ : (v w : N n) → N n
_•_ = zipWith _+_
-- Packaging up the normal forms
NF : ℕ → RawMonoid _ _
NF n = record { Carrier = N n ; _≈_ = _≡_ ; _∙_ = _•_ ; ε = empty }
-- The semantics of a normal form.
⟦_⟧⇓ : N n → Env n → Carrier
⟦ [] ⟧⇓ _ = ε
⟦ n ∷ v ⟧⇓ (a ∷ ρ) = (n × a) ∙ (⟦ v ⟧⇓ ρ)
-- We can decide if two normal forms are /syntactically/ equal.
infix 5 _≟_
_≟_ : DecidableEquality (N n)
_≟_ = _≡?_ ℕ._≟_
------------------------------------------------------------------------
-- Correctness of the constructions on normal forms
-- The empty bag stands for the unit ε.
ε-homo : (ρ : Env n) → ⟦ empty ⟧⇓ ρ ≈ ε
ε-homo [] = refl
ε-homo (a ∷ ρ) = begin
ε ∙ ⟦ empty ⟧⇓ ρ ≈⟨ identityˡ _ ⟩
⟦ empty ⟧⇓ ρ ≈⟨ ε-homo ρ ⟩
ε ∎
-- The singleton bag stands for a single variable.
sg-correct : (x : Fin n) (ρ : Env n) → ⟦ sg x ⟧⇓ ρ ≈ lookup ρ x
sg-correct zero (x ∷ ρ) = begin
(1 × x) ∙ ⟦ empty ⟧⇓ ρ ≈⟨ ∙-congʳ (×-homo-1 _) ⟩
x ∙ ⟦ empty ⟧⇓ ρ ≈⟨ ∙-congˡ (ε-homo ρ) ⟩
x ∙ ε ≈⟨ identityʳ _ ⟩
x ∎
sg-correct (suc x) (_ ∷ ρ) = begin
ε ∙ ⟦ sg x ⟧⇓ ρ ≈⟨ identityˡ _ ⟩
⟦ sg x ⟧⇓ ρ ≈⟨ sg-correct x ρ ⟩
lookup ρ x ∎
-- Normal form composition corresponds to the composition of the monoid.
∙-homo : ∀ v w (ρ : Env n) →
⟦ v • w ⟧⇓ ρ ≈ (⟦ v ⟧⇓ ρ ∙ ⟦ w ⟧⇓ ρ)
∙-homo [] [] _ = sym (identityˡ _)
∙-homo (l ∷ v) (m ∷ w) (a ∷ ρ) = begin
((l + m) × a) ∙ ⟦ v • w ⟧⇓ ρ ≈⟨ ∙-congʳ (×-homo-+ a l m) ⟩
(l × a) ∙ (m × a) ∙ ⟦ v • w ⟧⇓ ρ ≈⟨ ∙-congˡ (∙-homo v w ρ) ⟩
(l × a) ∙ (m × a) ∙ (⟦ v ⟧⇓ ρ ∙ ⟦ w ⟧⇓ ρ) ≈⟨ interchange _ _ _ _ ⟩
⟦ l ∷ v ⟧⇓ (a ∷ ρ) ∙ ⟦ m ∷ w ⟧⇓ (a ∷ ρ) ∎
------------------------------------------------------------------------
-- Packaging everything up
normal : NormalAPI
normal = record
{ NF = NF
; var = sg
; _≟_ = _≟_
; ⟦_⟧⇓ = ⟦_⟧⇓
; ⟦var_⟧⇓ = sg-correct
; ⟦⟧⇓-homo = λ ρ → record
{ isMagmaHomomorphism = record
{ isRelHomomorphism = record
{ cong = λ where ≡.refl → refl }
; homo = λ v w → ∙-homo v w ρ
}
; ε-homo = ε-homo ρ
}
}
open NormalAPI normal public
using (normalise; correct)