Skip to content

Commit ca1972c

Browse files
authored
Merge pull request #82 from VariantSync/variation-tree
Variation Trees
2 parents 08f20e8 + ef406dd commit ca1972c

22 files changed

Lines changed: 1112 additions & 85 deletions

src/Vatras/Data/Prop.agda

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
module Vatras.Data.Prop where
2+
3+
open import Data.Bool as Bool using (Bool)
4+
5+
data Prop (F : Set) : Set where
6+
true : Prop F
7+
false : Prop F
8+
var : F Prop F
9+
¬_ : Prop F Prop F
10+
_∧_ : Prop F Prop F Prop F
11+
12+
infix 23 ¬_
13+
infix 22 _∧_
14+
15+
_∨_ : {F} Prop F Prop F Prop F
16+
a ∨ b = ¬ (¬ a ∧ ¬ b)
17+
18+
_⇒_ : {F} Prop F Prop F Prop F
19+
a ⇒ b = ¬ a ∨ b
20+
21+
_⇔_ : {F} Prop F Prop F Prop F
22+
a ⇔ b = (a ⇒ b) ∧ (b ⇒ a)
23+
24+
Assignment : Set Set
25+
Assignment F = F Bool
26+
27+
eval : {F} Prop F Assignment F Bool
28+
eval true _ = Bool.true
29+
eval false _ = Bool.false
30+
eval (var p) c = c p
31+
eval (¬ p) c = Bool.not (eval p c)
32+
eval (p ∧ q) c = (eval p c) Bool.∧ (eval q c)
33+
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
module Vatras.Data.Prop.Properties {F : Set} where
2+
3+
import Data.Bool as Bool
4+
open import Data.Bool.Properties using (∧-comm; ∧-zeroˡ; ∧-zeroʳ)
5+
open import Data.Empty using (⊥)
6+
open import Data.Product as Product using (Σ; _×_; ∃-syntax; _,_)
7+
open import Data.Sum using (_⊎_; inj₁; inj₂)
8+
9+
open import Relation.Nullary.Negation renaming (¬_ to negate)
10+
open import Relation.Binary.PropositionalEquality as Eq using (_≡_; refl; cong; sym; trans)
11+
open Eq.≡-Reasoning
12+
13+
open import Vatras.Data.Prop
14+
open import Vatras.Util.AuxProofs using (true≢false)
15+
16+
all-true : Assignment F
17+
all-true _ = Bool.true
18+
19+
all-false : Assignment F
20+
all-false _ = Bool.false
21+
22+
NonContradiction :
23+
{b} {p : Prop F} (a : Assignment F)
24+
eval p a ≡ b
25+
eval (¬ p) a ≡ Bool.not b
26+
NonContradiction _ eq = cong Bool.not eq
27+
28+
NonContradiction' :
29+
(p : Prop F) (a : Assignment F)
30+
eval p a ≡ Bool.true
31+
eval p a ≡ Bool.false
32+
33+
NonContradiction' _ _ = true≢false
34+
35+
Satisfying : Prop F Assignment F Set
36+
Satisfying p a = eval p a ≡ Bool.true
37+
38+
Unsatisfying : Prop F Assignment F Set
39+
Unsatisfying p a = eval p a ≡ Bool.false
40+
41+
Satisfiable : Prop F Set
42+
Satisfiable p = Σ (Assignment F) (Satisfying p)
43+
44+
Falsifiable : Prop F Set
45+
Falsifiable p = Σ (Assignment F) (Unsatisfying p)
46+
47+
Tautology : Prop F Set
48+
Tautology p = a Satisfying p a
49+
50+
Contradiction : Prop F Set
51+
Contradiction p = a Unsatisfying p a
52+
53+
Const : Prop F Set
54+
Const p = Tautology p ⊎ Contradiction p
55+
56+
Const' : Prop F Set
57+
Const' p = ∃[ b ] ( a eval p a ≡ b)
58+
59+
Const→Const' : {p} Const p Const' p
60+
Const→Const' (inj₁ taut ) = Bool.true , taut
61+
Const→Const' (inj₂ contr) = Bool.false , contr
62+
63+
Const'→Const : {p} Const' p Const p
64+
Const'→Const (Bool.true , taut ) = inj₁ taut
65+
Const'→Const (Bool.false , contr) = inj₂ contr
66+
67+
Nonconst : Prop F Set
68+
Nonconst p = Satisfiable p × Falsifiable p
69+
70+
Nonconst' : Prop F Set
71+
Nonconst' p = negate (Const p)
72+
73+
Nonconst→Nonconst' : {p} Nonconst p Nonconst' p
74+
Nonconst→Nonconst' {p} (_ , (a , a-makes-false)) (inj₁ taut ) = NonContradiction' p a (taut a) a-makes-false
75+
Nonconst→Nonconst' {p} ((a , a-makes-true) , _) (inj₂ contr) = NonContradiction' p a a-makes-true (contr a)
76+
77+
sat-∧ˡ : p q
78+
Tautology p
79+
Satisfiable q
80+
Satisfiable (p ∧ q)
81+
sat-∧ˡ p q taut-p (a , sat) = a , (
82+
eval (p ∧ q) a ≡⟨⟩
83+
eval p a Bool.∧ eval q a ≡⟨ cong (Bool._∧ eval q a) (taut-p a) ⟩
84+
Bool.true Bool.∧ eval q a ≡⟨⟩
85+
eval q a ≡⟨ sat ⟩
86+
Bool.true ∎)
87+
88+
sat-∧ʳ : p q
89+
Tautology q
90+
Satisfiable p
91+
Satisfiable (p ∧ q)
92+
sat-∧ʳ p q taut-q (a , sat) = a , (
93+
eval (p ∧ q) a ≡⟨⟩
94+
eval p a Bool.∧ eval q a ≡⟨ cong (eval p a Bool.∧_) (taut-q a) ⟩
95+
eval p a Bool.∧ Bool.true ≡⟨ cong (Bool._∧ Bool.true) sat ⟩
96+
Bool.true ∎)
97+
98+
fal-∧ˡ : p q
99+
Falsifiable p
100+
Falsifiable (p ∧ q)
101+
fal-∧ˡ p q (a , unsat) = a , (
102+
eval (p ∧ q) a ≡⟨⟩
103+
eval p a Bool.∧ eval q a ≡⟨ cong (Bool._∧ eval q a) unsat ⟩
104+
Bool.false Bool.∧ eval q a ≡⟨ ∧-zeroˡ (eval q a) ⟩
105+
Bool.false ∎)
106+
107+
fal-∧ʳ : p q
108+
Falsifiable q
109+
Falsifiable (p ∧ q)
110+
fal-∧ʳ p q (a , unsat) = a , (
111+
eval (p ∧ q) a ≡⟨⟩
112+
eval p a Bool.∧ eval q a ≡⟨ cong (eval p a Bool.∧_) unsat ⟩
113+
eval p a Bool.∧ Bool.false ≡⟨ ∧-zeroʳ (eval p a) ⟩
114+
Bool.false ∎)
115+
116+
-- generalize?
117+
fal-∧-cong : p q
118+
Falsifiable (p ∧ q)
119+
Falsifiable (q ∧ p)
120+
fal-∧-cong p q (a , unsat) rewrite ∧-comm (eval p a) (eval q a) = a , unsat
121+
122+
taut-∧ : p q
123+
Tautology p
124+
Tautology q
125+
Tautology (p ∧ q)
126+
taut-∧ p q taut-p taut-q a rewrite taut-p a | taut-q a = refl
127+
128+
contr-∧ˡ : p q
129+
Contradiction p
130+
Contradiction (p ∧ q)
131+
contr-∧ˡ p q contr-p a rewrite contr-p a = refl
132+
133+
contr-∧ʳ : p q
134+
Contradiction q
135+
Contradiction (p ∧ q)
136+
contr-∧ʳ p q contr-q a =
137+
eval (p ∧ q) a ≡⟨⟩
138+
eval p a Bool.∧ eval q a ≡⟨ cong (eval p a Bool.∧_) (contr-q a) ⟩
139+
eval p a Bool.∧ Bool.false ≡⟨ ∧-comm (eval p a) Bool.false ⟩
140+
Bool.false ∎
141+

src/Vatras/Framework/Annotation/IndexedDimension.agda

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ IndexedDimension is used for conversions from NCC to NCC with lower arity (in pa
66
module Vatras.Framework.Annotation.IndexedDimension where
77

88
open import Data.Fin using (Fin)
9+
open import Data.Nat using (ℕ)
910
open import Data.Product using (_×_)
1011
open import Vatras.Util.Nat.AtLeast using (ℕ≥; toℕ; pred)
1112
open import Vatras.Framework.Definitions using (𝔽)
@@ -16,3 +17,6 @@ D with indices i ∈ ℕ, where 2 ≤ n.
1617
-}
1718
IndexedDimension : (D : 𝔽) (n : ℕ≥ 2) 𝔽
1819
IndexedDimension D n = D × Fin (toℕ (pred n))
20+
21+
Indexed : 𝔽 𝔽
22+
Indexed F = F × ℕ

src/Vatras/Framework/Definitions.agda

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,16 @@ and hence expressions are parameterized in the type of this atomic data.
6161
-}
6262
𝔼 : Set₂
6363
𝔼 = 𝔸 Set₁
64+
65+
-- some default atoms
66+
module _ where
67+
open import Data.String using (String; _≟_)
68+
69+
STRING : 𝔸
70+
STRING = String and _≟_
71+
72+
module _ where
73+
open import Data.Nat using (ℕ; _≟_)
74+
75+
NAT : 𝔸
76+
NAT = ℕ and _≟_

src/Vatras/Framework/Variants.agda

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ Rose trees are sized for termination checking.
3232
data Rose : Size 𝕍 where
3333
_-<_>- : {i} {A : 𝔸} atoms A List (Rose i A) Rose (↑ i) A
3434

35+
Forest : 𝕍
36+
Forest A = List (Rose ∞ A)
37+
3538
{-|
3639
Variants for gruler's language also form trees but opposed to rose trees,
3740
nodes are binary and data is stored only in leaves.
@@ -50,6 +53,12 @@ data GrulerVariant : 𝕍 where
5053
rose-leaf : {A : 𝔸} atoms A Rose ∞ A
5154
rose-leaf {A} a = a -< [] >-
5255

56+
forest-leaf : {A : 𝔸} atoms A Forest A
57+
forest-leaf a = rose-leaf a ∷ []
58+
59+
forest-singleton : {A : 𝔸} atoms A Forest A Forest A
60+
forest-singleton a l = a -< l >- ∷ []
61+
5362
{-|
5463
Interestingly, variants are also variability languages
5564
(and it does not matter how variants actually look like).

src/Vatras/Lang/ADT/Merge.agda

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
open import Vatras.Framework.Definitions
2+
module Vatras.Lang.ADT.Merge
3+
(V : 𝕍)
4+
(_+ᵥ_ : {A} V A V A V A)
5+
where
6+
7+
open import Data.Bool using (if_then_else_; true; false)
8+
open import Data.Bool.Properties using (if-float)
9+
open import Relation.Binary.PropositionalEquality using (refl; _≡_; _≗_)
10+
open Relation.Binary.PropositionalEquality.≡-Reasoning
11+
12+
open import Vatras.Util.AuxProofs using (if-cong)
13+
14+
import Vatras.Lang.ADT
15+
16+
module Named (F : 𝔽) where
17+
open Vatras.Lang.ADT F V
18+
19+
{-|
20+
Merges two ADTs.
21+
The resulting ADT denotes all possible compositions of variants, such that configuring the resulting ADT
22+
is equivalent to configuring both input ADTs and composing the resulting variants (see ⊕-spec below).
23+
This operations inherits all properties of the variant composition (e.g., commutativity, associativity etc).
24+
-}
25+
_⊕_ : {A} ADT A ADT A ADT A
26+
leaf l ⊕ leaf r = leaf (l +ᵥ r)
27+
leaf l ⊕ (E ⟨ el , er ⟩) = E ⟨ leaf l ⊕ el , leaf l ⊕ er ⟩
28+
(D ⟨ dl , dr ⟩) ⊕ r = D ⟨ dl ⊕ r , dr ⊕ r ⟩
29+
30+
⊕-spec : {A} (l r : ADT A) (c : Configuration)
31+
⟦ l ⊕ r ⟧ c ≡ ⟦ l ⟧ c +ᵥ ⟦ r ⟧ c
32+
⊕-spec (leaf l) (leaf r) c = refl
33+
⊕-spec (leaf l) (E ⟨ el , er ⟩) c with c E
34+
... | true = ⊕-spec (leaf l) el c
35+
... | false = ⊕-spec (leaf l) er c
36+
⊕-spec (D ⟨ dl , dr ⟩) r c with c D
37+
... | true = ⊕-spec dl r c
38+
... | false = ⊕-spec dr r c
39+
40+
---- Properties ----
41+
-- The merge operator inherits
42+
-- properties of the variant composition operator.
43+
--------------------
44+
45+
-- import Algebra.Definitions
46+
-- module Eq (A : 𝔸) where
47+
-- open Algebra.Definitions (_≡_ {A = V A}) using (Commutative) public
48+
49+
-- module Sem (A : 𝔸) where
50+
-- open Algebra.Definitions (_⊢_≣₁_ {A} ADTL) using (Commutative) public
51+
52+
-- ⊕-comm : {A} Eq.Commutative A _+ᵥ_ -> Sem.Commutative A _⊕_
53+
⊕-comm :
54+
( {A} (v w : V A) v +ᵥ w ≡ w +ᵥ v)
55+
---------------------------------------------
56+
( {A} (l r : ADT A) ⟦ l ⊕ r ⟧ ≗ ⟦ r ⊕ l ⟧)
57+
⊕-comm +ᵥ-comm l r c =
58+
⟦ l ⊕ r ⟧ c
59+
≡⟨ ⊕-spec l r c ⟩
60+
⟦ l ⟧ c +ᵥ ⟦ r ⟧ c
61+
≡⟨ +ᵥ-comm (⟦ l ⟧ c) (⟦ r ⟧ c) ⟩
62+
⟦ r ⟧ c +ᵥ ⟦ l ⟧ c
63+
≡⟨ ⊕-spec r l c ⟨
64+
⟦ r ⊕ l ⟧ c
65+
66+
67+
module Prop (F : 𝔽) where
68+
open import Vatras.Data.Prop
69+
open Vatras.Lang.ADT (Prop F) V
70+
open import Vatras.Lang.ADT.Prop F V
71+
open Named (Prop F)
72+
73+
⊕-specₚ : {A} (l r : ADT A) (c : Assignment F)
74+
⟦ l ⊕ r ⟧ₚ c ≡ ⟦ l ⟧ₚ c +ᵥ ⟦ r ⟧ₚ c
75+
⊕-specₚ (leaf v) (leaf r) c = refl
76+
⊕-specₚ (leaf l) (E ⟨ el , er ⟩) c with eval E c
77+
... | true = ⊕-specₚ (leaf l) el c
78+
... | false = ⊕-specₚ (leaf l) er c
79+
⊕-specₚ (D ⟨ dl , dr ⟩) r c with eval D c
80+
... | true = ⊕-specₚ dl r c
81+
... | false = ⊕-specₚ dr r c

src/Vatras/Lang/ADT/Prop.agda

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
open import Vatras.Framework.Definitions
2+
module Vatras.Lang.ADT.Prop (F : 𝔽) (V : 𝕍) where
3+
4+
open import Data.Bool using (if_then_else_)
5+
open import Vatras.Data.Prop using (Prop; Assignment; eval)
6+
open import Vatras.Framework.VariabilityLanguage
7+
open import Vatras.Lang.ADT (Prop F) V
8+
9+
⟦_⟧ₚ : 𝔼-Semantics V (Assignment F) ADT
10+
⟦ e ⟧ₚ c = ⟦ e ⟧ (λ D eval D c)
11+
12+
PropADTL : VariabilityLanguage V
13+
PropADTL = ⟪ ADT , Assignment F , ⟦_⟧ₚ ⟫

src/Vatras/Lang/ADT/Pushdown.agda

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
open import Vatras.Framework.Definitions using (𝔸; 𝔽; 𝕍; atoms)
2+
open import Data.List as List using (List; []; _∷_; _ʳ++_)
3+
4+
{-|
5+
This module provides a function for inserting artifacts at the top of ADTs.
6+
This operation means that any produced variant will have the given atom at the top.
7+
The parameter of this module is the constructor for adding an atom on top of existing variants.
8+
-}
9+
module Vatras.Lang.ADT.Pushdown (F : 𝔽) (V : 𝕍)
10+
(_-<_>- : {A} atoms A List (V A) V A)
11+
where
12+
13+
open import Data.Bool using (if_then_else_)
14+
import Data.Bool.Properties as Bool
15+
import Data.List.Properties as List
16+
open import Relation.Binary.PropositionalEquality as Eq using (_≡_; refl)
17+
open Eq.≡-Reasoning using (step-≡-⟨; step-≡-⟩; step-≡-∣; _∎)
18+
open import Size using (Size)
19+
20+
open import Vatras.Lang.ADT F V
21+
22+
push-down-artifact : {i : Size} {A : 𝔸} atoms A List (ADT A) ADT A
23+
push-down-artifact {A = A} a cs = go cs []
24+
module push-down-artifact-Implementation where
25+
go : {i : Size} List (ADT A) List (V A) ADT A
26+
go [] vs = leaf (a -< List.reverse vs >-)
27+
go (leaf v ∷ cs) vs = go cs (v ∷ vs)
28+
go (d ⟨ c₁ , c₂ ⟩ ∷ cs) vs = d ⟨ go (c₁ ∷ cs) vs , go (c₂ ∷ cs) vs ⟩
29+
30+
⟦push-down-artifact⟧ : {i : Size} {A : 𝔸}
31+
(a : atoms A)
32+
(cs : List (ADT A))
33+
(config : Configuration)
34+
⟦ push-down-artifact a cs ⟧ config ≡ a -< List.map (λ e ⟦ e ⟧ config) cs >-
35+
⟦push-down-artifact⟧ {A = A} a cs config = go' cs []
36+
where
37+
open push-down-artifact-Implementation
38+
39+
go' : {i : Size}
40+
(cs' : List (ADT A))
41+
(vs : List (V A))
42+
⟦ go a cs cs' vs ⟧ config ≡ a -< vs ʳ++ List.map (λ e ⟦ e ⟧ config) cs' >-
43+
go' [] vs = Eq.sym (Eq.cong₂ _-<_>- refl (Eq.trans (List.ʳ++-defn vs) (List.++-identityʳ (List.reverse vs))))
44+
go' (leaf v ∷ cs') vs = Eq.trans (go' cs' (v ∷ vs)) (Eq.cong₂ _-<_>- refl (List.++-ʳ++ List.[ v ] {ys = vs}))
45+
go' ((d ⟨ c₁ , c₂ ⟩) ∷ cs') vs =
46+
⟦ d ⟨ go a cs (c₁ ∷ cs') vs , go a cs (c₂ ∷ cs') vs ⟩ ⟧ config
47+
≡⟨⟩
48+
(if config d
49+
then ⟦ go a cs (c₁ ∷ cs') vs ⟧ config
50+
else ⟦ go a cs (c₂ ∷ cs') vs ⟧ config)
51+
≡⟨ Eq.cong₂ (if config d then_else_) (go' (c₁ ∷ cs') vs) (go' (c₂ ∷ cs') vs) ⟩
52+
(if config d
53+
then a -< vs ʳ++ List.map (λ e ⟦ e ⟧ config) (c₁ ∷ cs') >-
54+
else a -< vs ʳ++ List.map (λ e ⟦ e ⟧ config) (c₂ ∷ cs') >-)
55+
≡⟨ Bool.if-float (λ c a -< vs ʳ++ List.map (λ e ⟦ e ⟧ config) (c ∷ cs') >-) (config d) ⟨
56+
a -< vs ʳ++ List.map (λ e ⟦ e ⟧ config) ((if config d then c₁ else c₂) ∷ cs') >-
57+
≡⟨⟩
58+
a -< vs ʳ++ ⟦ if config d then c₁ else c₂ ⟧ config ∷ List.map (λ e ⟦ e ⟧ config) cs' >-
59+
≡⟨ Eq.cong₂ _-<_>- refl (Eq.cong₂ _ʳ++_ {x = vs} refl (Eq.cong₂ _∷_ (Bool.if-float (λ e ⟦ e ⟧ config) (config d)) refl)) ⟩
60+
a -< vs ʳ++ (if config d then ⟦ c₁ ⟧ config else ⟦ c₂ ⟧ config) ∷ List.map (λ e ⟦ e ⟧ config) cs' >-
61+
≡⟨⟩
62+
a -< vs ʳ++ ⟦ d ⟨ c₁ , c₂ ⟩ ⟧ config ∷ List.map (λ e ⟦ e ⟧ config) cs' >-
63+
≡⟨⟩
64+
a -< vs ʳ++ List.map (λ e ⟦ e ⟧ config) (d ⟨ c₁ , c₂ ⟩ ∷ cs') >-
65+

0 commit comments

Comments
 (0)