Skip to content

Commit 7d75889

Browse files
authored
Merge pull request #35 from pmbittner/translate-from-FST
Translate FST to VariantList and disprove translation to OC
2 parents cf1dd5b + 3ca7c93 commit 7d75889

File tree

11 files changed

+886
-147
lines changed

11 files changed

+886
-147
lines changed

src/Framework/Variants.agda

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ open import Size using (Size; ↑_; ∞)
1010

1111
open import Framework.Definitions using (𝕍; 𝔸; atoms)
1212
open import Framework.VariabilityLanguage
13-
open import Construct.Artifact as At using (_-<_>-; map-children) renaming (Syntax to Artifact; Construct to ArtifactC)
13+
open import Construct.Artifact as At using (map-children) renaming (Syntax to Artifact; Construct to ArtifactC)
1414

1515
open import Data.EqIndexedSet
1616

@@ -24,6 +24,8 @@ data Rose : Size → 𝕍 where
2424
rose-leaf : {A : 𝔸} atoms A Rose ∞ A
2525
rose-leaf {A} a = rose (At.leaf a)
2626

27+
pattern _-<_>- a cs = rose (a At.-< cs >-)
28+
2729
-- Variants are also variability languages
2830
Variant-is-VL : (V : 𝕍) VariabilityLanguage V
2931
Variant-is-VL V = ⟪ V , ⊤ , (λ e c e) ⟫
@@ -33,7 +35,7 @@ open import Data.Maybe using (nothing; just)
3335
open import Relation.Binary.PropositionalEquality as Peq using (_≡_; _≗_; refl)
3436
open Peq.≡-Reasoning
3537

36-
children-equality : {A : 𝔸} {a₁ a₂ : atoms A} {cs₁ cs₂ : List (Rose ∞ A)} rose (a₁ -< cs₁ >-)rose (a₂ -< cs₂ >-) cs₁ ≡ cs₂
38+
children-equality : {A : 𝔸} {a₁ a₂ : atoms A} {cs₁ cs₂ : List (Rose ∞ A)} a₁ -< cs₁ >- ≡ a₂ -< cs₂ >- cs₁ ≡ cs₂
3739
children-equality refl = refl
3840

3941
Artifact∈ₛRose : Artifact ∈ₛ Rose ∞
@@ -49,8 +51,8 @@ RoseVL = Variant-is-VL (Rose ∞)
4951

5052
open import Data.String using (String; _++_; intersperse)
5153
show-rose : {i} {A} (atoms A String) Rose i A String
52-
show-rose show-a (rose (a -< [] >-)) = show-a a
53-
show-rose show-a (rose (a -< es@(_ ∷ _) >-)) = show-a a ++ "-<" ++ (intersperse ", " (map (show-rose show-a) es)) ++ ">-"
54+
show-rose show-a (a -< [] >-) = show-a a
55+
show-rose show-a (a -< es@(_ ∷ _) >-) = show-a a ++ "-<" ++ (intersperse ", " (map (show-rose show-a) es)) ++ ">-"
5456

5557

5658
-- Variants can be encoded into other variability language.
@@ -123,24 +125,24 @@ rose-encoder Γ has c = record
123125
⟦_⟧ₚ = pcong ArtifactC Γ
124126

125127
h : (v : Rose ∞ A) (j : Config Γ) ⟦ t v ⟧ j ≡ v
126-
h (rose (a -< cs >-)) j =
128+
h (rose (a At.-< cs >-)) j =
127129
begin
128-
⟦ cons (C∈ₛΓ has) (map-children t (a -< cs >-)) ⟧ j
129-
≡⟨ resistant has (map-children t (a -< cs >-)) j ⟩
130-
(cons (C∈ₛV has) ∘ ⟦ map-children t (a -< cs >-)⟧ₚ) j
130+
⟦ cons (C∈ₛΓ has) (map-children t (a At.-< cs >-)) ⟧ j
131+
≡⟨ resistant has (map-children t (a At.-< cs >-)) j ⟩
132+
(cons (C∈ₛV has) ∘ ⟦ map-children t (a At.-< cs >-)⟧ₚ) j
131133
≡⟨⟩
132-
cons (C∈ₛV has) (⟦ map-children t (a -< cs >-) ⟧ₚ j)
134+
cons (C∈ₛV has) (⟦ map-children t (a At.-< cs >-) ⟧ₚ j)
133135
≡⟨⟩
134-
(cons (C∈ₛV has) ∘ flip ⟦_⟧ₚ j) (map-children t (a -< cs >-))
136+
(cons (C∈ₛV has) ∘ flip ⟦_⟧ₚ j) (map-children t (a At.-< cs >-))
135137
≡⟨⟩
136-
(cons (C∈ₛV has) ∘ flip ⟦_⟧ₚ j) (a -< map t cs >-)
137-
-- ≡⟨ Peq.cong (cons (C∈ₛV has) ∘ flip ⟦_⟧ₚ j) (Peq.cong (a -<_>-) {!!}) ⟩
138-
-- (cons (C∈ₛV has) ∘ flip ⟦_⟧ₚ j) (a -< cs >-)
138+
(cons (C∈ₛV has) ∘ flip ⟦_⟧ₚ j) (a At.-< map t cs >-)
139+
-- ≡⟨ Peq.cong (cons (C∈ₛV has) ∘ flip ⟦_⟧ₚ j) (Peq.cong (a At.-<_>-) {!!}) ⟩
140+
-- (cons (C∈ₛV has) ∘ flip ⟦_⟧ₚ j) (a At.-< cs >-)
139141
≡⟨ {!!}
140142
-- ≡⟨ bar _ ⟩
141-
-- rose (pcong ArtifactC Γ (a -< map t cs >-) j)
142-
-- ≡⟨ Peq.cong rose {!preservation ppp (a -< map t cs >-)!} ⟩
143-
rose (a -< cs >-)
143+
-- rose (pcong ArtifactC Γ (a At.-< map t cs >-) j)
144+
-- ≡⟨ Peq.cong rose {!preservation ppp (a At.-< map t cs >-)!} ⟩
145+
rose (a At.-< cs >-)
144146
145147
where
146148
module _ where
@@ -150,8 +152,8 @@ rose-encoder Γ has c = record
150152

151153
-- unprovable
152154
-- Imagine our domain A is pairs (a , b)
153-
-- Then cons could take an '(a , b) -< cs >-'
154-
-- and encode it as a 'rose ((b , a) -< cs >-)'
155+
-- Then cons could take an '(a , b) At.-< cs >-'
156+
-- and encode it as a 'rose ((b , a) At.-< cs >-)'
155157
-- for which exists an inverse snoc that just has
156158
-- to swap the arguments in the pair again.
157159
-- So we need a stronger axiom here that syntax
@@ -163,8 +165,8 @@ rose-encoder Γ has c = record
163165
sno : oc ∘ rose ≗ just
164166
sno a rewrite Peq.sym (bar a) = id-l (C∈ₛV has) a
165167

166-
foo : co (a -< cs >-) ≡ rose (a -< cs >-)
167-
foo = bar (a -< cs >-)
168+
foo : co (a At.-< cs >-) ≡ rose (a At.-< cs >-)
169+
foo = bar (a At.-< cs >-)
168170

169171
-- lp : (e : Rose ∞ A) ⟦ e ⟧ᵥ ⊆[ confi ] ⟦ t e ⟧
170172
-- lp (rose x) i =

src/Lang/All/Generic.agda

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1-
open import Framework.Definitions using (𝕍)
1+
open import Framework.Definitions using (𝕍; 𝔽; 𝔸)
22
open import Framework.Construct using (_∈ₛ_)
33
open import Construct.Artifact using () renaming (Syntax to Artifact)
44

55
module Lang.All.Generic (Variant : 𝕍) (Artifact∈ₛVariant : Artifact ∈ₛ Variant) where
66

7+
open import Size using (∞)
8+
9+
open import Framework.Variants using (Rose)
10+
711
module VariantList where
812
open import Lang.VariantList Variant public
913

@@ -30,4 +34,9 @@ module OC where
3034
open Lang.OC.Sem Variant Artifact∈ₛVariant public
3135

3236
module FST where
33-
open import Lang.FST renaming (FSTL-Sem to ⟦_⟧) public
37+
open import Lang.FST hiding (FST; FSTL-Sem; Conf) public
38+
39+
Configuration = Lang.FST.Conf
40+
41+
⟦_⟧ : {F : 𝔽} {A : 𝔸} Impose.SPL F A Configuration F Rose ∞ A
42+
⟦_⟧ {F} = Lang.FST.FSTL-Sem F

src/Lang/FST.agda

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ open import Relation.Binary.PropositionalEquality as Eq using (_≡_; refl)
3333
open Eq.≡-Reasoning
3434

3535
open import Framework.Annotation.Name using (Name)
36-
open import Framework.Variants using (Rose; rose; rose-leaf; children-equality)
36+
open import Framework.Variants using (Rose; _-<_>-; rose-leaf; children-equality)
3737
open import Framework.Composition.FeatureAlgebra
3838
open import Framework.VariabilityLanguage
3939
open import Framework.VariantMap using (VMap)
40-
open import Construct.Artifact as At using ()
40+
import Construct.Artifact as At
4141
open import Framework.Properties.Completeness using (Incomplete)
4242

4343
Conf : Set
@@ -53,7 +53,6 @@ open TODO-MOVE-TO-AUX-OR-USE-STL
5353
FST : Size 𝔼
5454
FST i = Rose i
5555

56-
pattern _-<_>- a cs = rose (a At.-< cs >-)
5756
fst-leaf = rose-leaf
5857

5958
induction : {A : 𝔸} {B : Set} (atoms A List B B) FST ∞ A B
@@ -505,7 +504,7 @@ module IncompleteOnRose where
505504
FST-is-incomplete complete with complete variants-0-and-1
506505
FST-is-incomplete complete | e , e⊆vs , vs⊆e = does-not-describe-variants-0-and-1 e (e⊆vs zero) (e⊆vs (suc zero))
507506

508-
cannotEncodeNeighbors : {A : 𝔸} (a b : atoms A) ∄[ e ] (∃[ c ] FSTL-Sem e c ≡ rose (a At.-< rose-leaf b ∷ rose-leaf b ∷ [] >-))
507+
cannotEncodeNeighbors : {A : 𝔸} (a b : atoms A) ∄[ e ] (∃[ c ] FSTL-Sem e c ≡ a -< rose-leaf b ∷ rose-leaf b ∷ [] >-)
509508
cannotEncodeNeighbors {A} a b (e , conf , ⟦e⟧c≡neighbors) =
510509
¬Unique b (Eq.subst (λ l Unique l) (children-equality ⟦e⟧c≡neighbors) (lemma (⊛-all (select conf (features e)))))
511510
where

src/Lang/OC.lagda.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ open import Data.String as String using (String)
2222
open import Size using (Size; ∞; ↑_)
2323
open import Function using (_∘_)
2424
25-
open import Framework.Variants
25+
open import Framework.Variants hiding (_-<_>-)
2626
open import Framework.VariabilityLanguage
2727
open import Framework.Construct
2828
open import Construct.Artifact as At using () renaming (Syntax to Artifact; Construct to Artifact-Construct)

src/Lang/OC/Alternative.agda

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
module Lang.OC.Alternative where
2+
3+
open import Data.List using (List; []; _∷_)
4+
open import Data.Sum as Sum using (_⊎_; inj₁; inj₂)
5+
open import Data.Bool using (true; false)
6+
open import Data.Nat using (zero; suc; _≟_; ℕ)
7+
open import Data.List.Relation.Binary.Sublist.Heterogeneous using (Sublist; _∷_; _∷ʳ_)
8+
open import Data.Product using (_,_; ∃-syntax)
9+
open import Relation.Binary.PropositionalEquality as Eq using (_≡_; refl)
10+
open import Size using (∞)
11+
12+
open import Framework.Definitions using (𝔽; 𝔸; atoms)
13+
open import Framework.Variants using (Rose; rose-leaf; _-<_>-; children-equality)
14+
open import Lang.All
15+
open OC using (WFOC; Root; all-oc)
16+
open import Lang.OC.Subtree using (Subtree; subtrees; subtreeₒ-recurse)
17+
18+
A : 𝔸
19+
A = ℕ , _≟_
20+
21+
cannotEncodeAlternative : {F : 𝔽}
22+
(e : WFOC F ∞ A)
23+
(∃[ c ] zero -< rose-leaf zero ∷ [] >- ≡ OC.⟦ e ⟧ c)
24+
(∃[ c ] zero -< rose-leaf (suc zero) ∷ [] >- ≡ OC.⟦ e ⟧ c)
25+
(zero -< [] >- ≡ OC.⟦ e ⟧ (all-oc false))
26+
Subtree (zero -< rose-leaf zero ∷ rose-leaf (suc zero) ∷ [] >-) (OC.⟦ e ⟧ (all-oc true))
27+
⊎ Subtree (zero -< rose-leaf (suc zero) ∷ rose-leaf zero ∷ [] >-) (OC.⟦ e ⟧ (all-oc true))
28+
cannotEncodeAlternative e@(Root zero cs) p₁ p₂ p₃ = Sum.map subtrees subtrees (mergeSubtrees' (sublist p₁) (sublist p₂))
29+
where
30+
sublist : {a : atoms A} {v : Rose ∞ A} (∃[ c ] a -< v ∷ [] >- ≡ OC.⟦ e ⟧ c) Sublist Subtree (v ∷ []) (OC.⟦ cs ⟧ₒ-recurse (all-oc true))
31+
sublist (c₁ , p₁) =
32+
Eq.subst
33+
(λ cs' Sublist Subtree cs' (OC.⟦ cs ⟧ₒ-recurse (all-oc true)))
34+
(children-equality (Eq.sym p₁))
35+
(subtreeₒ-recurse cs c₁ (all-oc true) (λ f p refl))
36+
37+
mergeSubtrees' : {cs : List (Rose ∞ A)}
38+
Sublist Subtree (rose-leaf zero ∷ []) cs
39+
Sublist Subtree (rose-leaf (suc zero) ∷ []) cs
40+
Sublist Subtree (rose-leaf zero ∷ rose-leaf (suc zero) ∷ []) cs
41+
⊎ Sublist Subtree (rose-leaf (suc zero) ∷ rose-leaf zero ∷ []) cs
42+
mergeSubtrees' (a ∷ʳ as₁) (.a ∷ʳ as₂) = Sum.map (a ∷ʳ_) (a ∷ʳ_) (mergeSubtrees' as₁ as₂)
43+
mergeSubtrees' (a₁ ∷ʳ as₁) (p₂ ∷ as₂) = inj₂ (p₂ ∷ as₁)
44+
mergeSubtrees' (p₁ ∷ as₁) (a₂ ∷ʳ as₂) = inj₁ (p₁ ∷ as₂)
45+
mergeSubtrees' (subtrees v ∷ as₁) (() ∷ as₂)

src/Lang/OC/Properties.agda

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
module Lang.OC.Properties where
2+
3+
open import Data.Bool using (true)
4+
open import Data.Maybe using (just)
5+
open import Data.Product using (_,_; ∃-syntax)
6+
open import Relation.Binary.PropositionalEquality using (_≡_; refl)
7+
open import Size using (∞)
8+
9+
open import Framework.Definitions using (𝔽; 𝔸)
10+
import Framework.Variants as V
11+
open import Lang.All
12+
open OC using (OC; _-<_>-; _❲_❳; ⟦_⟧ₒ; ⟦_⟧ₒ-recurse; all-oc)
13+
14+
⟦e⟧ₒtrue≡just : {F : 𝔽} {A : 𝔸} (e : OC F ∞ A) ∃[ v ] ⟦ e ⟧ₒ (all-oc true) ≡ just v
15+
⟦e⟧ₒtrue≡just (a -< cs >-) = a V.-< ⟦ cs ⟧ₒ-recurse (all-oc true) >- , refl
16+
⟦e⟧ₒtrue≡just (f ❲ e ❳) = ⟦e⟧ₒtrue≡just e

src/Lang/OC/Subtree.lagda.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
```agda
2+
module Lang.OC.Subtree where
3+
4+
open import Data.Bool using (true; false)
5+
open import Data.Empty using (⊥-elim)
6+
open import Data.List using (List; []; _∷_)
7+
open import Data.List.Relation.Binary.Sublist.Heterogeneous using (Sublist; []; _∷_; _∷ʳ_)
8+
open import Data.Maybe using (Maybe; nothing; just)
9+
open import Relation.Binary.PropositionalEquality as Eq using (_≡_; refl)
10+
open import Size using (∞)
11+
12+
open import Framework.Definitions using (𝔽; 𝔸; atoms)
13+
open import Framework.Variants as V hiding (_-<_>-)
14+
open import Lang.OC
15+
open Sem (Rose ∞) Artifact∈ₛRose
16+
open import Util.AuxProofs using (true≢false)
17+
```
18+
19+
Relates two variants iff the first argument is a subtree of the second argument.
20+
In other words: if some artifacts (including all their children) can be removed
21+
from the second variant to obtain the first variant exactly.
22+
```agda
23+
data Subtree {A : 𝔸} : Rose ∞ A → Rose ∞ A → Set₁ where
24+
subtrees : {a : atoms A} → {cs₁ cs₂ : List (Rose ∞ A)} → Sublist Subtree cs₁ cs₂ → Subtree (a V.-< cs₁ >-) (a V.-< cs₂ >-)
25+
```
26+
27+
Relates two optional variants using `Subtree`. This is mostly useful for
28+
relating `⟦_⟧ₒ` whereas `Subtree` is mostly used to relate `⟦_⟧`. It has the
29+
same semantics as `Subtree` but allows for the removal of the root artifact,
30+
which is fixed in `Subtree`.
31+
```agda
32+
data MaybeSubtree {A : 𝔸} : Maybe (Rose ∞ A) → Maybe (Rose ∞ A) → Set₁ where
33+
neither : MaybeSubtree nothing nothing
34+
one : {c : Rose ∞ A} → MaybeSubtree nothing (just c)
35+
both : {c₁ c₂ : Rose ∞ A} → Subtree c₁ c₂ → MaybeSubtree (just c₁) (just c₂)
36+
```
37+
38+
```agda
39+
Implies : {F : 𝔽} → Configuration F → Configuration F → Set
40+
Implies {F} c₁ c₂ = (f : F) → c₁ f ≡ true → c₂ f ≡ true
41+
```
42+
43+
If two configurations are related, their variants are also related. This result
44+
is enabled by the fact that OC cannot encode alternatives but only include or
45+
exclude subtrees. Hence, a subtree present in `c₂` can be removed, without any
46+
accidental additions anywhere in the variant, by configuring an option above it
47+
to `false` in `c₁`. However, the reverse is ruled out by the `Implies`
48+
assumption.
49+
50+
The following lemmas require mutual recursion because they are properties about
51+
functions (`⟦_⟧ₒ` and `⟦_⟧ₒ-recurse`) which are also defined mutually recursive.
52+
```agda
53+
mutual
54+
subtreeₒ : ∀ {F : 𝔽} {A : 𝔸} → (e : OC F ∞ A) → (c₁ c₂ : Configuration F) → Implies c₁ c₂ → MaybeSubtree (⟦ e ⟧ₒ c₁) (⟦ e ⟧ₒ c₂)
55+
subtreeₒ (a -< cs >-) c₁ c₂ c₁-implies-c₂ = both (subtrees (subtreeₒ-recurse cs c₁ c₂ c₁-implies-c₂))
56+
subtreeₒ (f ❲ c ❳) c₁ c₂ c₁-implies-c₂ with c₁ f in c₁-f | c₂ f in c₂-f
57+
subtreeₒ (f ❲ c ❳) c₁ c₂ c₁-implies-c₂ | false | false = neither
58+
subtreeₒ (f ❲ c ❳) c₁ c₂ c₁-implies-c₂ | false | true with ⟦ c ⟧ₒ c₂
59+
subtreeₒ (f ❲ c ❳) c₁ c₂ c₁-implies-c₂ | false | true | just _ = one
60+
subtreeₒ (f ❲ c ❳) c₁ c₂ c₁-implies-c₂ | false | true | nothing = neither
61+
subtreeₒ (f ❲ c ❳) c₁ c₂ c₁-implies-c₂ | true | false = ⊥-elim (true≢false refl (Eq.trans (Eq.sym (c₁-implies-c₂ f c₁-f)) c₂-f))
62+
subtreeₒ (f ❲ c ❳) c₁ c₂ c₁-implies-c₂ | true | true with ⟦ c ⟧ₒ c₁ | ⟦ c ⟧ₒ c₂ | subtreeₒ c c₁ c₂ c₁-implies-c₂
63+
subtreeₒ (f ❲ c ❳) c₁ c₂ c₁-implies-c₂ | true | true | .nothing | .nothing | neither = neither
64+
subtreeₒ (f ❲ c ❳) c₁ c₂ c₁-implies-c₂ | true | true | .nothing | .(just _) | one = one
65+
subtreeₒ (f ❲ c ❳) c₁ c₂ c₁-implies-c₂ | true | true | .(just _) | .(just _) | both p = both p
66+
```
67+
68+
From `subtreeₒ`, we know that `map (λ c → ⟦ c ⟧ₒ c₁)` can produce `nothing`s
69+
instead of `just`s at some outputs of `map (λ c → ⟦ c ⟧ₒ c₂)`. All other
70+
elements must be the same. Hence, `catMaybes` results in a sublist.
71+
```agda
72+
subtreeₒ-recurse : ∀ {F : 𝔽} {A : 𝔸} → (cs : List (OC F ∞ A)) → (c₁ c₂ : Configuration F) → Implies c₁ c₂ → Sublist Subtree (⟦ cs ⟧ₒ-recurse c₁) (⟦ cs ⟧ₒ-recurse c₂)
73+
subtreeₒ-recurse [] c₁ c₂ c₁-implies-c₂ = []
74+
subtreeₒ-recurse (c ∷ cs) c₁ c₂ c₁-implies-c₂ with ⟦ c ⟧ₒ c₁ | ⟦ c ⟧ₒ c₂ | subtreeₒ c c₁ c₂ c₁-implies-c₂
75+
... | .nothing | .nothing | neither = subtreeₒ-recurse cs c₁ c₂ c₁-implies-c₂
76+
... | .nothing | just c' | one = c' ∷ʳ subtreeₒ-recurse cs c₁ c₂ c₁-implies-c₂
77+
... | .(just _) | .(just _) | both p = p ∷ subtreeₒ-recurse cs c₁ c₂ c₁-implies-c₂
78+
```
79+
80+
This theorem still holds if we guarantee that there is an artifact at the root.
81+
```agda
82+
subtree : ∀ {F : 𝔽} {A : 𝔸} → (e : WFOC F ∞ A) → (c₁ c₂ : Configuration F) → Implies c₁ c₂ → Subtree (⟦ e ⟧ c₁) (⟦ e ⟧ c₂)
83+
subtree {F} {A} (Root a cs) c₁ c₂ c₁-implies-c₂ = subtrees (subtreeₒ-recurse cs c₁ c₂ c₁-implies-c₂)
84+
```

0 commit comments

Comments
 (0)