Skip to content

Commit 5993340

Browse files
authored
Merge pull request #80 from VariantSync/module-structure-refactorings
Module structure refactorings
2 parents 2100a96 + ec4b3f4 commit 5993340

71 files changed

Lines changed: 1526 additions & 1395 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
*.#*
66
.dir-locals.el
77

8+
# emacs' agda mode
9+
src/agda2-mode*
10+
811
# build
912
src/cc
1013
src/Main

default.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
},
1010
}:
1111
pkgs.agdaPackages.mkDerivation {
12-
version = "1.0";
12+
version = "2.0";
1313
pname = "Vatras";
1414
src = with pkgs.lib.fileset;
1515
toSource {

src/Vatras/Lang/2CC.lagda.md

Lines changed: 14 additions & 177 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,19 @@
33
## Module
44

55
```agda
6-
open import Vatras.Framework.Definitions
7-
module Vatras.Lang.2CC where
6+
open import Vatras.Framework.Definitions using (𝔽; 𝔸; atoms; 𝔼; ℂ)
7+
module Vatras.Lang.2CC (Dimension : 𝔽) where
88
```
99

1010
## Imports
1111

1212
```agda
13-
open import Data.Bool using (Bool; true; false; if_then_else_)
14-
open import Data.List
15-
using (List; []; _∷_; lookup)
16-
renaming (map to mapl)
17-
open import Data.Product using (_,_)
18-
open import Function using (id)
13+
open import Data.Bool using (Bool; if_then_else_)
14+
open import Data.List as List using (List)
1915
open import Size using (Size; ↑_; ∞)
2016
2117
open import Vatras.Framework.Variants as V using (Rose)
22-
open import Vatras.Framework.VariabilityLanguage
18+
open import Vatras.Framework.VariabilityLanguage using (𝔼-Semantics; VariabilityLanguage; ⟪_,_,_⟫)
2319
```
2420

2521
## Syntax
@@ -31,9 +27,9 @@ or a binary choice `D ⟨ l , r ⟩` between two sub-expressions `l` and `r`, wh
3127
to identify the choice upon configuration.
3228
Dimensions `D` can be of any given type `Dimension : 𝔽`.
3329
```agda
34-
data 2CC (Dimension : 𝔽) : Size → 𝔼 where
35-
_-<_>- : ∀ {i A} → atoms A → List (2CC Dimension i A) → 2CC Dimension (↑ i) A
36-
_⟨_,_⟩ : ∀ {i A} → Dimension → 2CC Dimension i A → 2CC Dimension i A → 2CC Dimension (↑ i) A
30+
data 2CC : Size → 𝔼 where
31+
_-<_>- : ∀ {i A} → atoms A → List (2CC i A) → 2CC (↑ i) A
32+
_⟨_,_⟩ : ∀ {i A} → Dimension → 2CC i A → 2CC i A → 2CC (↑ i) A
3733
```
3834

3935
## Semantics
@@ -47,175 +43,16 @@ We define `true` to mean choosing the left alternative and `false` to choose the
4743
Defining it the other way around is also possible but we have to pick one definition and stay consistent.
4844
We choose this order to follow the known _if c then a else b_ pattern where the evaluation of a condition _c_ to true means choosing the then-branch, which is the left one.
4945
```agda
50-
Configuration : (Dimension : 𝔽) →
51-
Configuration Dimension = Dimension → Bool
46+
Configuration : ℂ
47+
Configuration = Dimension → Bool
5248
53-
⟦_⟧ : ∀ {i : Size} {Dimension : 𝔽} → 𝔼-Semantics (Rose ∞) (Configuration Dimension) (2CC Dimension i)
54-
⟦ a -< cs >- ⟧ c = a V.-< mapl (λ e → ⟦ e ⟧ c) cs >-
49+
⟦_⟧ : ∀ {i : Size} → 𝔼-Semantics (Rose ∞) Configuration (2CC i)
50+
⟦ a -< cs >- ⟧ c = a V.-< List.map (λ e → ⟦ e ⟧ c) cs >-
5551
⟦ D ⟨ l , r ⟩ ⟧ c =
5652
if c D
5753
then ⟦ l ⟧ c
5854
else ⟦ r ⟧ c
5955
60-
2CCL : ∀ {i : Size} (Dimension : 𝔽) → VariabilityLanguage (Rose ∞)
61-
2CCL {i} Dimension = ⟪ 2CC Dimension i , Configuration Dimension , ⟦_⟧ ⟫
62-
```
63-
64-
In the following, we prove some interesting properties about binary choice calculus,
65-
known from the respective papers.
66-
67-
```agda
68-
module _ {Dimension : 𝔽} where
69-
```
70-
71-
## Properties
72-
73-
Some transformation rules:
74-
```agda
75-
open Data.List using ([_])
76-
open import Data.List.Properties using (map-∘; map-cong)
77-
open import Data.Nat using (ℕ)
78-
open import Data.Vec as Vec using (Vec; toList; zipWith)
79-
import Data.Vec.Properties as Vec
80-
import Vatras.Util.Vec as Vec
81-
82-
open import Relation.Binary.PropositionalEquality as Eq using (_≡_; refl; _≗_)
83-
84-
module Properties where
85-
open import Vatras.Framework.Relation.Expression (Rose ∞)
86-
87-
module _ {A : 𝔸} where
88-
{-|
89-
Given a choice between two artifacts with the same atom 'a',
90-
we can factor out this atom 'a' outside of the choice because no matter
91-
how we configure the choice, the resulting expression will always have 'a'
92-
at the top.
93-
-}
94-
choice-factoring : ∀ {i} {D : Dimension} {a : atoms A} {n : ℕ}
95-
→ (xs ys : Vec (2CC Dimension i A) n)
96-
------------------------------------------------
97-
→ 2CCL Dimension ⊢
98-
D ⟨ a -< toList xs >- , a -< toList ys >- ⟩
99-
≣₁ a -< toList (zipWith (D ⟨_,_⟩) xs ys) >-
100-
choice-factoring {i} {D} {a} {n} xs ys c =
101-
⟦ D ⟨ a -< toList xs >- , a -< toList ys >- ⟩ ⟧ c
102-
≡⟨⟩
103-
(if c D then ⟦ a -< toList xs >- ⟧ c else ⟦ a -< toList ys >- ⟧ c)
104-
≡⟨ lemma (c D) ⟩
105-
a V.-< toList (zipWith (λ x y → if c D then ⟦ x ⟧ c else ⟦ y ⟧ c) xs ys) >-
106-
≡⟨⟩
107-
a V.-< toList (zipWith (λ x y → ⟦ D ⟨ x , y ⟩ ⟧ c) xs ys) >-
108-
≡⟨ Eq.cong (a V.-<_>-) (Eq.cong toList (Vec.map-zipWith (λ e → ⟦ e ⟧ c) (D ⟨_,_⟩) xs ys)) ⟨
109-
a V.-< toList (Vec.map (λ e → ⟦ e ⟧ c) (zipWith (D ⟨_,_⟩) xs ys)) >-
110-
≡⟨ Eq.cong (a V.-<_>-) (Vec.toList-map (λ e → ⟦ e ⟧ c) (zipWith (D ⟨_,_⟩) xs ys)) ⟩
111-
a V.-< mapl (λ e → ⟦ e ⟧ c) (toList (zipWith (D ⟨_,_⟩) xs ys)) >-
112-
≡⟨⟩
113-
⟦ a -< toList (zipWith (D ⟨_,_⟩) xs ys) >- ⟧ c
114-
115-
where
116-
open Eq.≡-Reasoning
117-
lemma : (b : Bool) →
118-
(if b then ⟦ a -< toList xs >- ⟧ c else ⟦ a -< toList ys >- ⟧ c)
119-
≡ a V.-< toList (zipWith (λ x y → if b then ⟦ x ⟧ c else ⟦ y ⟧ c) xs ys) >-
120-
lemma false =
121-
(if false then ⟦ a -< toList xs >- ⟧ c else ⟦ a -< toList ys >- ⟧ c)
122-
≡⟨⟩
123-
⟦ a -< toList ys >- ⟧ c
124-
≡⟨⟩
125-
a V.-< mapl (λ e → ⟦ e ⟧ c) (toList ys) >-
126-
≡⟨ Eq.cong (a V.-<_>-) (Vec.toList-map (λ e → ⟦ e ⟧ c) ys) ⟨
127-
a V.-< toList (Vec.map (λ y → ⟦ y ⟧ c) ys) >-
128-
≡⟨ Eq.cong (a V.-<_>-) (Eq.cong toList (Vec.zipWith₂ (λ y → ⟦ y ⟧ c) xs ys)) ⟨
129-
a V.-< toList (zipWith (λ x y → ⟦ y ⟧ c) xs ys) >-
130-
≡⟨⟩
131-
a V.-< toList (zipWith (λ x y → if false then ⟦ x ⟧ c else ⟦ y ⟧ c) xs ys) >-
132-
133-
lemma true =
134-
(if true then ⟦ a -< toList xs >- ⟧ c else ⟦ a -< toList ys >- ⟧ c)
135-
≡⟨⟩
136-
⟦ a -< toList xs >- ⟧ c
137-
≡⟨⟩
138-
a V.-< mapl (λ e → ⟦ e ⟧ c) (toList xs) >-
139-
≡⟨ Eq.cong (a V.-<_>-) (Vec.toList-map (λ e → ⟦ e ⟧ c) xs) ⟨
140-
a V.-< toList (Vec.map (λ x → ⟦ x ⟧ c) xs) >-
141-
≡⟨ Eq.cong (a V.-<_>-) (Eq.cong toList (Vec.zipWith₁ (λ x → ⟦ x ⟧ c) xs ys)) ⟨
142-
a V.-< toList (zipWith (λ x y → ⟦ x ⟧ c) xs ys) >-
143-
≡⟨⟩
144-
a V.-< toList (zipWith (λ x y → if true then ⟦ x ⟧ c else ⟦ y ⟧ c) xs ys) >-
145-
146-
147-
{-|
148-
A choice between two equal alternatives is no choice.
149-
No matter how we configure the choice, the result stays the same.
150-
-}
151-
choice-idempotency : ∀ {D} {e : 2CC Dimension ∞ A}
152-
---------------------------------
153-
→ 2CCL Dimension ⊢ D ⟨ e , e ⟩ ≣₁ e
154-
choice-idempotency {D} {e} c with c D
155-
... | false = refl
156-
... | true = refl
157-
158-
{-|
159-
If the left alternative of a choice is semantically equivalent
160-
to another expression l′, we can replace the left alternative with l′.
161-
-}
162-
choice-l-congruence : ∀ {i : Size} {D : Dimension} {l l′ r : 2CC Dimension i A}
163-
→ 2CCL Dimension ⊢ l ≣₁ l′
164-
---------------------------------------
165-
→ 2CCL Dimension ⊢ D ⟨ l , r ⟩ ≣₁ D ⟨ l′ , r ⟩
166-
choice-l-congruence {D = D} l≣l′ c with c D
167-
... | false = refl
168-
... | true = l≣l′ c
169-
170-
{-|
171-
If the right alternative of a choice is semantically equivalent
172-
to another expression r′, we can replace the right alternative with r′.
173-
-}
174-
choice-r-congruence : ∀ {i : Size} {D : Dimension} {l r r′ : 2CC Dimension i A}
175-
→ 2CCL Dimension ⊢ r ≣₁ r′
176-
---------------------------------------
177-
→ 2CCL Dimension ⊢ D ⟨ l , r ⟩ ≣₁ D ⟨ l , r′ ⟩
178-
choice-r-congruence {D = D} r≣r′ c with c D
179-
... | false = r≣r′ c
180-
... | true = refl
181-
```
182-
183-
## Utility
184-
185-
```agda
186-
open Data.List using (concatMap) renaming (_++_ to _++l_)
187-
188-
{-|
189-
Recursively, collect all dimensions used in a binary CC expression
190-
-}
191-
dims : ∀ {i : Size} {A : 𝔸} → 2CC Dimension i A → List Dimension
192-
dims (_ -< es >-) = concatMap dims es
193-
dims (D ⟨ l , r ⟩) = D ∷ (dims l ++l dims r)
194-
```
195-
196-
## Show
197-
198-
```agda
199-
open import Data.String as String using (String; _++_; intersperse)
200-
module Pretty (show-D : Dimension → String) where
201-
open import Vatras.Show.Lines
202-
203-
show : ∀ {i} → 2CC Dimension i (String , String._≟_) → String
204-
show (a -< [] >-) = a
205-
show (a -< es@(_ ∷ _) >-) = a ++ "-<" ++ (intersperse ", " (mapl show es)) ++ ">-"
206-
show (D ⟨ l , r ⟩) = show-D D ++ "⟨" ++ (show l) ++ ", " ++ (show r) ++ "⟩"
207-
208-
pretty : ∀ {i : Size} → 2CC Dimension i (String , String._≟_) → Lines
209-
pretty (a -< [] >-) = > a
210-
pretty (a -< es@(_ ∷ _) >-) = do
211-
> a ++ "-<"
212-
indent 2 do
213-
intersperseCommas (mapl pretty es)
214-
> ">-"
215-
pretty (D ⟨ l , r ⟩) = do
216-
> show-D D ++ "⟨"
217-
indent 2 do
218-
appendToLastLine "," (pretty l)
219-
pretty r
220-
> "⟩"
56+
2CCL : ∀ {i : Size} → VariabilityLanguage (Rose ∞)
57+
2CCL {i} = ⟪ 2CC i , Configuration , ⟦_⟧ ⟫
22158
```
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
open import Vatras.Framework.Definitions using (𝔽; 𝔸; atoms; 𝔼; ℂ)
2+
module Vatras.Lang.2CC.Properties {Dimension : 𝔽} {A : 𝔸} where
3+
4+
{-
5+
In the following, we prove some interesting properties about binary choice calculus,
6+
known from the respective papers.
7+
-}
8+
9+
open import Size using (Size; ∞)
10+
open import Data.Bool using (Bool; true; false; if_then_else_)
11+
import Data.List as List
12+
open import Data.Nat using (ℕ)
13+
open import Data.Vec as Vec using (Vec; toList; zipWith)
14+
import Data.Vec.Properties as Vec
15+
open import Relation.Binary.PropositionalEquality as Eq using (_≡_; refl)
16+
17+
import Vatras.Util.Vec as Vec
18+
open import Vatras.Framework.Variants as V using (Rose)
19+
open import Vatras.Framework.Relation.Expression (Rose ∞) using (_⊢_≣₁_)
20+
open import Vatras.Lang.2CC Dimension using (2CC; _-<_>-; _⟨_,_⟩; 2CCL; ⟦_⟧)
21+
22+
{-|
23+
Given a choice between two artifacts with the same atom 'a',
24+
we can factor out this atom 'a' outside of the choice because no matter
25+
how we configure the choice, the resulting expression will always have 'a'
26+
at the top.
27+
-}
28+
choice-factoring : {i} {D : Dimension} {a : atoms A} {n : ℕ}
29+
(xs ys : Vec (2CC i A) n)
30+
------------------------------------------------
31+
2CCL ⊢
32+
D ⟨ a -< toList xs >- , a -< toList ys >- ⟩
33+
≣₁ a -< toList (zipWith (D ⟨_,_⟩) xs ys) >-
34+
choice-factoring {i} {D} {a} {n} xs ys c =
35+
⟦ D ⟨ a -< toList xs >- , a -< toList ys >- ⟩ ⟧ c
36+
≡⟨⟩
37+
(if c D then ⟦ a -< toList xs >- ⟧ c else ⟦ a -< toList ys >- ⟧ c)
38+
≡⟨ lemma (c D) ⟩
39+
a V.-< toList (zipWith (λ x y if c D then ⟦ x ⟧ c else ⟦ y ⟧ c) xs ys) >-
40+
≡⟨⟩
41+
a V.-< toList (zipWith (λ x y ⟦ D ⟨ x , y ⟩ ⟧ c) xs ys) >-
42+
≡⟨ Eq.cong (a V.-<_>-) (Eq.cong toList (Vec.map-zipWith (λ e ⟦ e ⟧ c) (D ⟨_,_⟩) xs ys)) ⟨
43+
a V.-< toList (Vec.map (λ e ⟦ e ⟧ c) (zipWith (D ⟨_,_⟩) xs ys)) >-
44+
≡⟨ Eq.cong (a V.-<_>-) (Vec.toList-map (λ e ⟦ e ⟧ c) (zipWith (D ⟨_,_⟩) xs ys)) ⟩
45+
a V.-< List.map (λ e ⟦ e ⟧ c) (toList (zipWith (D ⟨_,_⟩) xs ys)) >-
46+
≡⟨⟩
47+
⟦ a -< toList (zipWith (D ⟨_,_⟩) xs ys) >- ⟧ c
48+
49+
where
50+
open Eq.≡-Reasoning
51+
lemma : (b : Bool)
52+
(if b then ⟦ a -< toList xs >- ⟧ c else ⟦ a -< toList ys >- ⟧ c)
53+
≡ a V.-< toList (zipWith (λ x y if b then ⟦ x ⟧ c else ⟦ y ⟧ c) xs ys) >-
54+
lemma false =
55+
(if false then ⟦ a -< toList xs >- ⟧ c else ⟦ a -< toList ys >- ⟧ c)
56+
≡⟨⟩
57+
⟦ a -< toList ys >- ⟧ c
58+
≡⟨⟩
59+
a V.-< List.map (λ e ⟦ e ⟧ c) (toList ys) >-
60+
≡⟨ Eq.cong (a V.-<_>-) (Vec.toList-map (λ e ⟦ e ⟧ c) ys) ⟨
61+
a V.-< toList (Vec.map (λ y ⟦ y ⟧ c) ys) >-
62+
≡⟨ Eq.cong (a V.-<_>-) (Eq.cong toList (Vec.zipWith₂ (λ y ⟦ y ⟧ c) xs ys)) ⟨
63+
a V.-< toList (zipWith (λ x y ⟦ y ⟧ c) xs ys) >-
64+
≡⟨⟩
65+
a V.-< toList (zipWith (λ x y if false then ⟦ x ⟧ c else ⟦ y ⟧ c) xs ys) >-
66+
67+
lemma true =
68+
(if true then ⟦ a -< toList xs >- ⟧ c else ⟦ a -< toList ys >- ⟧ c)
69+
≡⟨⟩
70+
⟦ a -< toList xs >- ⟧ c
71+
≡⟨⟩
72+
a V.-< List.map (λ e ⟦ e ⟧ c) (toList xs) >-
73+
≡⟨ Eq.cong (a V.-<_>-) (Vec.toList-map (λ e ⟦ e ⟧ c) xs) ⟨
74+
a V.-< toList (Vec.map (λ x ⟦ x ⟧ c) xs) >-
75+
≡⟨ Eq.cong (a V.-<_>-) (Eq.cong toList (Vec.zipWith₁ (λ x ⟦ x ⟧ c) xs ys)) ⟨
76+
a V.-< toList (zipWith (λ x y ⟦ x ⟧ c) xs ys) >-
77+
≡⟨⟩
78+
a V.-< toList (zipWith (λ x y if true then ⟦ x ⟧ c else ⟦ y ⟧ c) xs ys) >-
79+
80+
81+
{-|
82+
A choice between two equal alternatives is no choice.
83+
No matter how we configure the choice, the result stays the same.
84+
-}
85+
choice-idempotency : {D} {e : 2CC ∞ A}
86+
---------------------------------
87+
2CCL ⊢ D ⟨ e , e ⟩ ≣₁ e
88+
choice-idempotency {D} {e} c with c D
89+
... | false = refl
90+
... | true = refl
91+
92+
{-|
93+
If the left alternative of a choice is semantically equivalent
94+
to another expression l′, we can replace the left alternative with l′.
95+
-}
96+
choice-l-congruence : {i : Size} {D : Dimension} {l l′ r : 2CC i A}
97+
2CCL ⊢ l ≣₁ l′
98+
---------------------------------------
99+
2CCL ⊢ D ⟨ l , r ⟩ ≣₁ D ⟨ l′ , r ⟩
100+
choice-l-congruence {D = D} l≣l′ c with c D
101+
... | false = refl
102+
... | true = l≣l′ c
103+
104+
{-|
105+
If the right alternative of a choice is semantically equivalent
106+
to another expression r′, we can replace the right alternative with r′.
107+
-}
108+
choice-r-congruence : {i : Size} {D : Dimension} {l r r′ : 2CC i A}
109+
2CCL ⊢ r ≣₁ r′
110+
---------------------------------------
111+
2CCL ⊢ D ⟨ l , r ⟩ ≣₁ D ⟨ l , r′ ⟩
112+
choice-r-congruence {D = D} r≣r′ c with c D
113+
... | false = r≣r′ c
114+
... | true = refl

src/Vatras/Lang/2CC/Show.agda

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
open import Vatras.Framework.Definitions
2+
open import Data.String as String using (String; _++_)
3+
module Vatras.Lang.2CC.Show {Dimension : 𝔽} (show-D : Dimension String) where
4+
5+
open import Size using (Size)
6+
open import Data.Product using (_,_)
7+
open import Data.List as List using ([]; _∷_)
8+
9+
open import Vatras.Show.Lines
10+
open import Vatras.Lang.2CC Dimension using (2CC; _⟨_,_⟩; _-<_>-)
11+
12+
show : {i} 2CC i (String , String._≟_) String
13+
show (a -< [] >-) = a
14+
show (a -< es@(_ ∷ _) >-) = a ++ "-<" ++ (String.intersperse ", " (List.map show es)) ++ ">-"
15+
show (D ⟨ l , r ⟩) = show-D D ++ "⟨" ++ (show l) ++ ", " ++ (show r) ++ "⟩"
16+
17+
pretty : {i : Size} 2CC i (String , String._≟_) Lines
18+
pretty (a -< [] >-) = > a
19+
pretty (a -< es@(_ ∷ _) >-) = do
20+
> a ++ "-<"
21+
indent 2 do
22+
intersperseCommas (List.map pretty es)
23+
> ">-"
24+
pretty (D ⟨ l , r ⟩) = do
25+
> show-D D ++ "⟨"
26+
indent 2 do
27+
appendToLastLine "," (pretty l)
28+
pretty r
29+
> "⟩"

0 commit comments

Comments
 (0)