Decompositions
Haskell implementation of the Overview/Decompositions
Sections
Definition
A functional definition set decomposition is a model that consists of a tree of fuds that are contingent on components.
The set of functional definition set decompositions $\mathcal{D}_{\mathrm{F}}$ is a subset of the trees of pairs of (i) states, $\mathcal{S}$, and (ii) functional definition sets, $\mathcal{F}$,
\[
\begin{eqnarray}
\mathcal{D}_{\mathrm{F}} &\subset& \mathrm{trees}(\mathcal{S} \times \mathcal{F})
\end{eqnarray}
\]
The Tree a
generic type is described in Notation. The DecompFud
type is defined as a Tree
of pairs of State
and Fud
,
newtype DecompFud = DecompFud (Tree (State,Fud))
A fud decomposition is constructed from a tree of pairs of states and fuds,
treePairStateFudsDecompFud :: Tree (State,Fud) -> Maybe DecompFud
Consider the deck of cards example,
let lluu ll = fromJust $ listsSystem [(v,Set.fromList ww) | (v,ww) <- ll]
let [suit,rank] = map VarStr ["suit","rank"]
[hearts,clubs,diamonds,spades] = map ValStr ["hearts","clubs","diamonds","spades"]
[jack,queen,king,ace] = map ValStr ["J","Q","K","A"]
let uu = lluu [
(suit, [hearts, clubs, diamonds, spades]),
(rank, [jack,queen,king,ace] ++ map ValInt [2..10])]
let vv = Set.fromList [suit, rank]
rp uu
"{(rank,{A,J,K,Q,2,3,4,5,6,7,8,9,10}),(suit,{clubs,diamonds,hearts,spades})}"
rp vv
"{rank,suit}"
let aa = unit (cart uu vv)
rpln $ aall aa
"({(rank,A),(suit,clubs)},1 % 1)"
"({(rank,A),(suit,diamonds)},1 % 1)"
"({(rank,A),(suit,hearts)},1 % 1)"
"({(rank,A),(suit,spades)},1 % 1)"
"({(rank,J),(suit,clubs)},1 % 1)"
"({(rank,J),(suit,diamonds)},1 % 1)"
...
"({(rank,9),(suit,hearts)},1 % 1)"
"({(rank,9),(suit,spades)},1 % 1)"
"({(rank,10),(suit,clubs)},1 % 1)"
"({(rank,10),(suit,diamonds)},1 % 1)"
"({(rank,10),(suit,hearts)},1 % 1)"
"({(rank,10),(suit,spades)},1 % 1)"
A transform $T_{\mathrm{c}}$ can be constructed relating the suit to the colour,
let lltt kk ww qq = trans (unit (Set.fromList [llss (zip (kk ++ ww) ll) | ll <- qq])) (Set.fromList ww)
let colour = VarStr "colour"
red = ValStr "red"; black = ValStr "black"
let ttc = lltt [suit] [colour] [
[hearts, red],
[clubs, black],
[diamonds, red],
[spades, black]]
Another transform $T_{\mathrm{t}}$ can be constructed relating the rank to whether it is a pip card or a face card,
let pip_or_face = VarStr "pip_or_face"
pip = ValStr "pip"; face = ValStr "face"
let ttt = lltt [rank] [pip_or_face] ([
[ace, pip],
[king, face],
[queen, face],
[jack, face]] ++
[[ValInt i, pip] | i <- [2..10]])
Let another transform $T_{\mathrm{op}}$ with a derived variable odd_pip
have value yes
for odd pip cards, and value no
otherwise,
let odd_pip = VarStr "odd_pip"
yes = ValStr "yes"; no = ValStr "no"
let ttop = lltt [rank] [odd_pip] ([
[ace, yes],
[king, no],
[queen, no],
[jack, no]] ++
[[ValInt i, no] | i <- [2,4..10]] ++
[[ValInt i, yes] | i <- [3,5..9]])
Let $D$ be a fud decomposition, $D \in \mathcal{D}_{\mathrm{F}}$, be constructed from a list of paths,
let lldf zz = fromJust $ treePairStateFudsDecompFud $ pathsTree $ Set.fromList [[(llss ss, llff ff) | (ss,ff) <- ll] | ll <- zz]
let df = lldf [
[([], [ttop]), ([(odd_pip, no)], [ttc, ttt])],
[([], [ttop]), ([(odd_pip, yes)], [ttc])]]
The set of fuds is $\mathrm{fuds}(D) := \{F : ((\cdot,F),\cdot) \in \mathrm{nodes}(D)\}$,
decompFudsSetFud :: DecompFud -> Set.Set Fud
For example,
let dfqq = decompFudsSetFud
dfqq df == Set.fromList [llff [ttop], llff [ttc], llff [ttc, ttt]]
True
The underlying is $\mathrm{und}(D) := \bigcup \{\mathrm{und}(F) : F \in \mathrm{fuds}(D)\}$,
decompFudsUnderlying :: DecompFud -> Set.Set Variable
For example,
let dfund = decompFudsUnderlying
rp $ dfund df
"{rank,suit}"
Fud decompositions are constrained such that each of the states in child pairs are states in the derived variables of the parent fud, \[ \forall D \in \mathcal{D}_{\mathrm{F}}~\forall ((\cdot,F),E) \in \mathrm{nodes}(D)~\forall ((S,\cdot),\cdot) \in E~(S \in \mathrm{dom}((F^{\mathrm{T}})^{-1})) \]
fder (llff [ttop]) == Set.singleton odd_pip
True
The root nodes have no parent and so their states are constrained to be null, $\forall D \in \mathcal{D}_{\mathrm{F}}~\forall ((S,\cdot),\cdot) \in D~(S = \emptyset)$,
decompFudsTreePairStateFud :: DecompFud -> Tree (State,Fud)
For example,
let dfzz = decompFudsTreePairStateFud
let (ss,_) = Set.findMax (treesRoots (dfzz df))
ss == stateEmpty
True
The fud decomposition, $D$, can be converted to a list of paths,
let dfll = Set.toList . treesPaths . dfzz
:t dfll df
dfll df :: [[(State, Fud)]]
rpln $ map (fst . unzip) $ dfll df
"[{},{(odd_pip,no)}]"
"[{},{(odd_pip,yes)}]"
dfll df !! 0 !! 0 == (llss [], llff [ttop])
True
dfll df !! 0 !! 1 == (llss [(odd_pip, no)], llff [ttc, ttt])
True
dfll df !! 1 !! 1 == (llss [(odd_pip, yes)], llff [ttc])
True
Given a fud decomposition $D \in \mathcal{D}_{\mathrm{F}}$ having underlying variables $V = \mathrm{und}(D)$, each fud $F \in \mathrm{fuds}(D)$ is contingent on the component $C \in \mathrm{B}(V^{\mathrm{C}})$ implied by the union of the ancestor derived states in the derived variables of the union of the ancestor fuds. Let $L$ be a path in the fud decomposition, $L \in \mathrm{paths}(D)$. Then for each child fud $(\cdot,F) = L_i$, where $i \in \{2 \ldots |L|\}$, the union of the ancestor derived states is $R = \bigcup \{S : j \in \{2 \ldots i\},~(S,\cdot) = L_j\}$, the union of the ancestor fuds is $G = \bigcup \{H : j \in \{1 \ldots i-1\},~(\cdot,H) = L_j\}$, and so the contingent component is $(G^{\mathrm{T}})^{-1}(R)$. In the case where the underlying of the ancestor fud, $G$, is the whole substrate, $\mathrm{und}(G)=V$, then the component is $C = (G^{\mathrm{T}})^{-1}(R) \subseteq V^{\mathrm{C}}$. In the deck of cards example, the second path of the decomposition, $D$, is where odd_pip
equals yes
,
let ll = dfll df !! 1
length ll
2
rp $ fst $ unzip ll
"[{},{(odd_pip,yes)}]"
let rr = foldl1 sunion [ss | (ss,_) <- take 2 ll]
rp rr
"{(odd_pip,yes)}"
let gg = foldl1 funion [ff | (_,ff) <- take 1 ll]
gg == llff [ttop]
True
The expanded component contains all of the odd pip cards,
let vvc = unit (cart uu vv)
let inv = transformsInverse
let cc = (inv (fftt gg) Map.! rr) `mul` vvc
rpln $ aall cc
"({(rank,A),(suit,clubs)},1 % 1)"
"({(rank,A),(suit,diamonds)},1 % 1)"
"({(rank,A),(suit,hearts)},1 % 1)"
"({(rank,A),(suit,spades)},1 % 1)"
"({(rank,3),(suit,clubs)},1 % 1)"
"({(rank,3),(suit,diamonds)},1 % 1)"
"({(rank,3),(suit,hearts)},1 % 1)"
"({(rank,3),(suit,spades)},1 % 1)"
"({(rank,5),(suit,clubs)},1 % 1)"
"({(rank,5),(suit,diamonds)},1 % 1)"
"({(rank,5),(suit,hearts)},1 % 1)"
"({(rank,5),(suit,spades)},1 % 1)"
"({(rank,7),(suit,clubs)},1 % 1)"
"({(rank,7),(suit,diamonds)},1 % 1)"
"({(rank,7),(suit,hearts)},1 % 1)"
"({(rank,7),(suit,spades)},1 % 1)"
"({(rank,9),(suit,clubs)},1 % 1)"
"({(rank,9),(suit,diamonds)},1 % 1)"
"({(rank,9),(suit,hearts)},1 % 1)"
"({(rank,9),(suit,spades)},1 % 1)"
The function $\mathrm{cont} \in \mathcal{D}_{\mathrm{F}} \to \mathrm{P}(\mathcal{A} \times \mathcal{F})$ returns the set of component-fud pairs of the fud decomposition. When the fud decomposition, $D$, is applied to a histogram $A \in \mathcal{A}$ in variables $\mathrm{vars}(A) = V$, each fud transform is applied to the contingent slice, $A * C * F^{\mathrm{T}}$ where $(C,F) \in \mathrm{cont}(D)$. Two fuds on the same path $(\cdot,F_1) \in L_j$ and $(\cdot,F_2) \in L_i$ where $L \in \mathrm{paths}(D)$ and $j<i$, are such that the fud $(C_1,F_1) \in \mathrm{cont}(D)$ nearer the root has a component which is a superset of the component of the fud $(C_2,F_2) \in \mathrm{cont}(D)$ nearer the leaves, $C_1 \supset C_2$. So the slice nearer the root is greater than or equal to the slice nearer the leaves, $A * C_1 \geq A * C_2$. That is, the fuds are more and more selectively contingent along the fud decomposition’s paths, and so are applied to smaller and smaller slices. In the case of the deck of cards example, the component, $C$, which consists of the odd pip cards, is a subset of the decomposition root component, which is the cartesian, $V^{\mathrm{C}}$,
cc `leq` vvc
True
(aa `mul` cc) `leq` (aa `mul` vvc)
True
In the case where each of the slice derived are diagonalised, $\forall (C,F) \in \mathrm{cont}(D)~(\mathrm{diagonal}(A * C * F^{\mathrm{T}}))$, the fud decomposition, $D$, is a contingent, layered, redundant model of the sample histogram, $A$.
Conversion to transform
A fud decomposition is a model, so it can be converted to a functional transform, $D^{\mathrm{T}} \in \mathcal{T}_{\mathrm{f}}$. The partition of the fud decomposition transform is equal to the set of components corresponding to those fud derived states that are not parent derived states in the decomposition tree, $\bigcup \{\mathrm{dom}((F^{\mathrm{T}})^{-1}) \setminus \{S : ((S,\cdot),\cdot) \in E\} : ((\cdot,F),E) \in \mathrm{nodes}(D)\}$. The resultant transform has the same underlying variables as the fud decomposition, $\mathrm{und}(D^{\mathrm{T}}) = \mathrm{und}(D)$.
Decompositions are rarely converted to transforms in practice. Useful decompositions generally have large substrates and so the components of a partition of the cartesian are very large. This is because volume varies exponentially with dimension, $v = d^n$. In practice, rather than applying decomposition transforms to sample histograms to obtain the derived histogram, $A * D^{\mathrm{T}}$, decompositions are applied directly to sample histograms to obtain a tree of pairs of derived state $S$ and derived slice histogram $A * C * F^{\mathrm{T}}$,
decompFudsHistogramsApply :: DecompFud -> Histogram -> Tree (State,Histogram)
For example,
let dfapplyll aa df = Set.toList $ treesPaths $ decompFudsHistogramsApply df aa
:t aa `dfapplyll` df
aa `dfapplyll` df :: [[(State, Histogram)]]
rpln $ map (map (\(ss,bb) -> (ss, vars bb, size bb))) $ aa `dfapplyll` df
"[({},{odd_pip},52 % 1),({(odd_pip,no)},{colour,pip_or_face},32 % 1)]"
"[({},{odd_pip},52 % 1),({(odd_pip,yes)},{colour},20 % 1)]"
rpln $ map (fst . unzip) $ aa `dfapplyll` df
"[{},{(odd_pip,no)}]"
"[{},{(odd_pip,yes)}]"
rpln $ aall $ snd $ aa `dfapplyll` df !! 0 !! 0
"({(odd_pip,no)},32 % 1)"
"({(odd_pip,yes)},20 % 1)"
rpln $ aall $ snd $ aa `dfapplyll` df !! 0 !! 1
"({(colour,black),(pip_or_face,face)},6 % 1)"
"({(colour,black),(pip_or_face,pip)},10 % 1)"
"({(colour,red),(pip_or_face,face)},6 % 1)"
"({(colour,red),(pip_or_face,pip)},10 % 1)"
rpln $ aall $ snd $ aa `dfapplyll` df !! 1 !! 1
"({(colour,black)},10 % 1)"
"({(colour,red)},10 % 1)"
A similar function preserves the underlying variables, $A * C * \mathrm{his}(F^{\mathrm{T}})~\%~(\mathrm{und}(F) \cup \mathrm{der}(F))$,
decompFudsHistogramsMultiply :: DecompFud -> Histogram -> Tree (State,Histogram)
For example,
let dfmulll aa df = Set.toList $ treesPaths $ decompFudsHistogramsMultiply df aa
:t aa `dfmulll` df
aa `dfmulll` df :: [[(State, Histogram)]]
rpln $ map (map (\(ss,bb) -> (ss, vars bb, size bb))) $ aa `dfmulll` df
"[({},{odd_pip,rank,suit},52 % 1),({(odd_pip,no)},{colour,pip_or_face,rank,suit},32 % 1)]"
"[({},{odd_pip,rank,suit},52 % 1),({(odd_pip,yes)},{colour,rank,suit},20 % 1)]"
rpln $ map (fst . unzip) $ aa `dfmulll` df
"[{},{(odd_pip,no)}]"
"[{},{(odd_pip,yes)}]"
rpln $ aall $ snd $ aa `dfmulll` df !! 0 !! 0
"({(odd_pip,no),(rank,J),(suit,clubs)},1 % 1)"
"({(odd_pip,no),(rank,J),(suit,diamonds)},1 % 1)"
"({(odd_pip,no),(rank,J),(suit,hearts)},1 % 1)"
"({(odd_pip,no),(rank,J),(suit,spades)},1 % 1)"
"({(odd_pip,no),(rank,K),(suit,clubs)},1 % 1)"
"({(odd_pip,no),(rank,K),(suit,diamonds)},1 % 1)"
...
"({(odd_pip,yes),(rank,7),(suit,hearts)},1 % 1)"
"({(odd_pip,yes),(rank,7),(suit,spades)},1 % 1)"
"({(odd_pip,yes),(rank,9),(suit,clubs)},1 % 1)"
"({(odd_pip,yes),(rank,9),(suit,diamonds)},1 % 1)"
"({(odd_pip,yes),(rank,9),(suit,hearts)},1 % 1)"
"({(odd_pip,yes),(rank,9),(suit,spades)},1 % 1)"
rpln $ aall $ snd $ aa `dfmulll` df !! 0 !! 1
"({(colour,black),(pip_or_face,face),(rank,J),(suit,clubs)},1 % 1)"
"({(colour,black),(pip_or_face,face),(rank,J),(suit,spades)},1 % 1)"
"({(colour,black),(pip_or_face,face),(rank,K),(suit,clubs)},1 % 1)"
"({(colour,black),(pip_or_face,face),(rank,K),(suit,spades)},1 % 1)"
"({(colour,black),(pip_or_face,face),(rank,Q),(suit,clubs)},1 % 1)"
"({(colour,black),(pip_or_face,face),(rank,Q),(suit,spades)},1 % 1)"
...
"({(colour,red),(pip_or_face,pip),(rank,6),(suit,diamonds)},1 % 1)"
"({(colour,red),(pip_or_face,pip),(rank,6),(suit,hearts)},1 % 1)"
"({(colour,red),(pip_or_face,pip),(rank,8),(suit,diamonds)},1 % 1)"
"({(colour,red),(pip_or_face,pip),(rank,8),(suit,hearts)},1 % 1)"
"({(colour,red),(pip_or_face,pip),(rank,10),(suit,diamonds)},1 % 1)"
"({(colour,red),(pip_or_face,pip),(rank,10),(suit,hearts)},1 % 1)"
rpln $ aall $ snd $ aa `dfmulll` df !! 1 !! 1
"({(colour,black),(rank,A),(suit,clubs)},1 % 1)"
"({(colour,black),(rank,A),(suit,spades)},1 % 1)"
"({(colour,black),(rank,3),(suit,clubs)},1 % 1)"
"({(colour,black),(rank,3),(suit,spades)},1 % 1)"
"({(colour,black),(rank,5),(suit,clubs)},1 % 1)"
"({(colour,black),(rank,5),(suit,spades)},1 % 1)"
...
"({(colour,red),(rank,5),(suit,diamonds)},1 % 1)"
"({(colour,red),(rank,5),(suit,hearts)},1 % 1)"
"({(colour,red),(rank,7),(suit,diamonds)},1 % 1)"
"({(colour,red),(rank,7),(suit,hearts)},1 % 1)"
"({(colour,red),(rank,9),(suit,diamonds)},1 % 1)"
"({(colour,red),(rank,9),(suit,hearts)},1 % 1)"
Queries may be made too. In this case, however, the model underlying equals the entire substrate, $\mathrm{und}(D) = K = V$, so there are no label variables. The query is merely classified by the model, $D$,
decompFudsHistogramsHistogramsQuery :: DecompFud -> Histogram -> Histogram -> Tree (State,Histogram)
For example,
let red aa ll = setVarsHistogramsReduce (Set.fromList ll) aa
queryll qq df aa ll = map (map (\(ss,bb) -> (ss, norm (bb `red` ll)))) $ Set.toList $ treesPaths $ decompFudsHistogramsHistogramsQuery df aa qq
let qq = single (llss [(rank,ace),(suit,spades)]) 1
:t queryll qq df aa []
queryll qq df aa [] :: [[(State, Histogram)]]
rpln $ map (fst . unzip) $ queryll qq df aa []
"[{},{(odd_pip,yes)}]"
rpln $ aarr $ snd $ queryll qq df aa [] !! 0 !! 1
"({},1.0)"
let qq = single (llss [(rank,queen),(suit,hearts)]) 1
rpln $ map (fst. unzip) $ queryll qq df aa []
"[{},{(odd_pip,no)}]"
Conversion to fud
The tree of a fud decomposition is sometimes unwieldy, so consider the fud decomposition fud, $D^{\mathrm{F}} \in \mathcal{F}$, which is the intermediate fud used in the construction of the fud decomposition transform, $D^{\mathrm{T}}$. The decomposition fud is defined as the union of the decomposition fuds and the nullable fud, $D^{\mathrm{F}} := \bigcup \mathrm{fuds}(D) \cup \mathrm{nullable}(U)(D^{\mathrm{D}})$. The nullable fud, $\mathrm{nullable}(U)(D^{\mathrm{D}})$, is defined in section ‘Decompositions’ of the paper. It consists of a layer of transforms which is added on top of the union of the decomposition fuds, $\bigcup \mathrm{fuds}(D)$. Each derived variable in the fud union, $w \in \mathrm{der}(F)$ where $F \in \mathrm{fuds}(D)$, is in the underlying of a corresponding transform, $w \in \mathrm{und}(T_w)$, in the nullable layer. The transform derived consists of a nullable variable $\{w’\} = \mathrm{der}(T_w)$. This nullable variable, $w’$, has the same values as its underlying variable, $w$, but with an additional $\mathrm{null}$ value, $U_{w’} = U_w \cup \{\mathrm{null}\}$. If the fud, $F$, is not the root fud, there is also a contingent variable $c$ with values corresponding to the fud’s in-slice and out-slice states, $U_c = \{\mathrm{in},\mathrm{out}\}$. That is, given contingent state $S \in C^{\mathrm{S}}$, where $(C,F) \in \mathrm{cont}(D)$, the derived state, $R$, is such that $(c,\mathrm{in}) \in R$. Similarly, if $S \in V^{\mathrm{CS}} \setminus C^{\mathrm{S}}$, then $(c,\mathrm{out}) \in R$. The underlying of nullable variable’s transform will also contain the contingent variable, $\{c,w\} = \mathrm{und}(T_w)$. The nullable variable, $w’$, is constrained by the transform, $T_w$, to be in the $\mathrm{null}$ value whenever the contingent variable, $c$, is in the $\mathrm{out}$ value, and to be in the value of the underlying variable, $w$, otherwise. That is, $(c,\mathrm{out}) \in R \implies (w’,\mathrm{null}) \in R$, and $(c,\mathrm{in}) \in R \implies (w’,R_w) \in R$. In this way, there is no need to navigate the slices of the decomposition. The fud decomposition fud, $D^{\mathrm{F}}$, can be analysed by examining the effective states of reductions to its nullable derived variables, $\mathrm{der}(D^{\mathrm{F}})$.
Substrate decompositions
Given a set of substrate variables $V$, the set of substrate fud decompositions $\mathcal{D}_{\mathrm{F},U,V}$ is a subset of fud decompositions, $\mathcal{D}_{\mathrm{F},U,V} \subset \mathcal{D}_{\mathrm{F}}$, that contain only substrate fuds, $\forall D \in \mathcal{D}_{\mathrm{F},U,V}~\forall F \in \mathrm{fuds}(D)~(F \in \mathcal{F}_{U,V})$. In addition, each fud is unique in a path, $\forall D \in \mathcal{D}_{\mathrm{F},U,V}~\forall L \in \mathrm{paths}(D)~(|\{F : (\cdot,(\cdot,F)) \in L\}| = |L|)$.
systemsSetVarsSetDecompFudSubstrate :: System -> Set.Set Variable -> Maybe (Set.Set DecompFud)
For example,
let dfvv uu = fromJust $ systemsSetVarsSetDecompFudSubstrate uu (uvars uu)
Set.size $ dfvv $ systemEmpty
2
rpln $ Set.toList $ dfvv $ systemEmpty
"{(({},{}),{(({},{({({({ { {} } },{ {} })},1 % 1)},{ { { {} } } })}),{})})}"
"{(({},{({({({ { {} } },{ {} })},1 % 1)},{ { { {} } } })}),{(({({ { {} } },{ {} })},{}),{})})}"
Similarly, the infinite-layer substrate fud decompositions $\mathcal{D}_{\mathrm{F},\infty,U,V}$ is the superset of the substrate fud decompositions, $\mathcal{D}_{\mathrm{F},\infty,U,V} \supset \mathcal{D}_{\mathrm{F},U,V}$, that contain only infinite-layer substrate fuds, $\forall D \in \mathcal{D}_{\mathrm{F},\infty,U,V}~\forall F \in \mathrm{fuds}(D)~(F \in \mathcal{F}_{\infty,U,V})$. The cardinality of the infinite-layer substrate fud decomposition set is infinite, $|\mathcal{D}_{\mathrm{F},\infty,U,V}| = \infty$.
Example - a weather forecast
Some of the concepts above regarding functional definition set decompositions can be demonstrated with the sample of some weather measurements created in States, histories and histograms, Transforms and Functional definition sets. Here we add an additional pressure variable pressureb
with the same values as pressure
. We also add an additional history of stormy weather,
let lluu ll = fromJust $ listsSystem [(v,Set.fromList ww) | (v,ww) <- ll]
llhh vv ev = fromJust $ listsHistory [(IdInt i, llss (zip vv ll)) | (i,ll) <- ev]
hadd hh gg = fromJust $ pairHistoriesAdd hh gg
ared aa vv = setVarsHistogramsReduce vv aa
red aa ll = setVarsHistogramsReduce (Set.fromList ll) aa
ssplit ll aa = Set.toList (setVarsSetStatesSplit (Set.fromList ll) (states aa))
lltt kk ww qq = trans (unit (Set.fromList [llss (zip (kk ++ ww) ll) | ll <- qq])) (Set.fromList ww)
lldf zz = fromJust $ treePairStateFudsDecompFud $ pathsTree $ Set.fromList [[(llss ss, llff ff) | (ss,ff) <- ll] | ll <- zz]
query qq tt aa ll = norm (qq `tmul` tt `mul` ttaa tt `mul` aa `red` ll)
ent = histogramsEntropy
cent = transformsHistogramsEntropyComponent
rent aa bb = let a = fromRational (size aa); b = fromRational (size bb) in (a+b) * ent (aa `add` bb) - a * ent aa - b * ent bb
tlent tt aa ll = setVarsTransformsHistogramsEntropyLabel (vars aa `Set.difference` (Set.fromList ll)) tt aa
tlalgn tt aa ll = algn (aa `mul` ttaa tt `ared` (der tt `Set.union` Set.fromList ll))
layer ff v = fudsSetVarsLayer ff (Set.singleton v)
dfmulll aa df = Set.toList $ treesPaths $ decompFudsHistogramsMultiply df aa
queryll qq df aa ll = map (map (\(ss,bb) -> (ss, norm (bb `red` ll)))) $ Set.toList $ treesPaths $ decompFudsHistogramsHistogramsQuery df aa qq
let [pressure,pressureb,cloud,wind,rain] = map VarStr ["pressure","pressureb","cloud","wind","rain"]
let [low,medium,high,none,light,heavy,strong] = map ValStr ["low","medium","high","none","light","heavy","strong"]
let uu = lluu [
(pressure, [low,medium,high]),
(pressureb, [low,medium,high]),
(cloud, [none,light,heavy]),
(wind, [none,light,strong]),
(rain, [none,light,heavy])]
let vv = uvars uu
let hh1 = llhh [pressure,pressureb,cloud,wind,rain] [
(1,[high,high,none,none,none]),
(2,[medium,high,light,none,light]),
(3,[high,medium,none,light,none]),
(4,[low,medium,heavy,strong,heavy]),
(5,[low,low,none,light,light]),
(6,[medium,medium,none,light,light]),
(7,[low,medium,heavy,light,heavy]),
(8,[high,medium,none,light,none]),
(9,[medium,low,light,strong,heavy]),
(10,[medium,medium,light,light,light]),
(11,[high,high,light,light,heavy]),
(12,[medium,high,none,none,none]),
(13,[medium,low,light,none,none]),
(14,[high,medium,light,strong,light]),
(15,[medium,medium,none,light,light]),
(16,[low,medium,heavy,strong,heavy]),
(17,[low,low,heavy,light,heavy]),
(18,[high,medium,none,none,none]),
(19,[low,low,light,none,light]),
(20,[high,high,none,none,none])]
let hh2 = llhh [pressure,pressureb,cloud,wind,rain] [
(1,[high,low,none,none,light]),
(2,[low,high,light,none,light]),
(3,[low,high,heavy,strong,heavy]),
(4,[low,high,heavy,light,heavy]),
(5,[high,low,light,strong,heavy]),
(6,[low,high,light,light,light]),
(7,[low,high,light,light,heavy]),
(8,[low,high,heavy,strong,heavy]),
(9,[high,low,heavy,light,heavy]),
(10,[high,low,light,none,light])]
let aa = hhaa (hh1 `hadd` hh2)
let vvc = unit (cart uu vv)
rp uu
"{(cloud,{heavy,light,none}),(pressure,{high,low,medium}),(pressureb,{high,low,medium}),(rain,{heavy,light,none}),(wind,{light,none,strong})}"
rp vv
"{cloud,pressure,pressureb,rain,wind}"
rpln $ aall aa
"({(cloud,heavy),(pressure,high),(pressureb,low),(rain,heavy),(wind,light)},1 % 1)"
"({(cloud,heavy),(pressure,low),(pressureb,high),(rain,heavy),(wind,light)},1 % 1)"
"({(cloud,heavy),(pressure,low),(pressureb,high),(rain,heavy),(wind,strong)},2 % 1)"
"({(cloud,heavy),(pressure,low),(pressureb,low),(rain,heavy),(wind,light)},1 % 1)"
"({(cloud,heavy),(pressure,low),(pressureb,medium),(rain,heavy),(wind,light)},1 % 1)"
"({(cloud,heavy),(pressure,low),(pressureb,medium),(rain,heavy),(wind,strong)},2 % 1)"
"({(cloud,light),(pressure,high),(pressureb,high),(rain,heavy),(wind,light)},1 % 1)"
"({(cloud,light),(pressure,high),(pressureb,low),(rain,heavy),(wind,strong)},1 % 1)"
"({(cloud,light),(pressure,high),(pressureb,low),(rain,light),(wind,none)},1 % 1)"
"({(cloud,light),(pressure,high),(pressureb,medium),(rain,light),(wind,strong)},1 % 1)"
"({(cloud,light),(pressure,low),(pressureb,high),(rain,heavy),(wind,light)},1 % 1)"
"({(cloud,light),(pressure,low),(pressureb,high),(rain,light),(wind,light)},1 % 1)"
"({(cloud,light),(pressure,low),(pressureb,high),(rain,light),(wind,none)},1 % 1)"
"({(cloud,light),(pressure,low),(pressureb,low),(rain,light),(wind,none)},1 % 1)"
"({(cloud,light),(pressure,medium),(pressureb,high),(rain,light),(wind,none)},1 % 1)"
"({(cloud,light),(pressure,medium),(pressureb,low),(rain,heavy),(wind,strong)},1 % 1)"
"({(cloud,light),(pressure,medium),(pressureb,low),(rain,none),(wind,none)},1 % 1)"
"({(cloud,light),(pressure,medium),(pressureb,medium),(rain,light),(wind,light)},1 % 1)"
"({(cloud,none),(pressure,high),(pressureb,high),(rain,none),(wind,none)},2 % 1)"
"({(cloud,none),(pressure,high),(pressureb,low),(rain,light),(wind,none)},1 % 1)"
"({(cloud,none),(pressure,high),(pressureb,medium),(rain,none),(wind,light)},2 % 1)"
"({(cloud,none),(pressure,high),(pressureb,medium),(rain,none),(wind,none)},1 % 1)"
"({(cloud,none),(pressure,low),(pressureb,low),(rain,light),(wind,light)},1 % 1)"
"({(cloud,none),(pressure,medium),(pressureb,high),(rain,none),(wind,none)},1 % 1)"
"({(cloud,none),(pressure,medium),(pressureb,medium),(rain,light),(wind,light)},2 % 1)"
size aa
30 % 1
Create a transform $T_{\mathrm{cw}}$ which relates cloud
and wind
,
let cloud_and_wind = VarStr "cloud_and_wind"
let ttcw = lltt [cloud,wind] [cloud_and_wind] [
[none, none, none],
[none, light, light],
[none, strong, light],
[light, none, light],
[light, light, light],
[light, strong, light],
[heavy, none, strong],
[heavy, light, strong],
[heavy, strong, strong]]
Create a transform $T_{\mathrm{cp}}$ that relates cloud
and pressure
,
let cloud_and_pressure = VarStr "cloud_and_pressure"
let ttcp = lltt [cloud,pressure] [cloud_and_pressure] [
[none, high, none],
[none, medium, light],
[none, low, light],
[light, high, light],
[light, medium, light],
[light, low, light],
[heavy, high, strong],
[heavy, medium, strong],
[heavy, low, strong]]
Create a transform $T_{\mathrm{sc}}$ which rolls together the none
and light
values of the cloud
variable,
let storm_cloud = VarStr "storm_cloud"
let ttsc = lltt [cloud] [storm_cloud] [
[none, light],
[light, light],
[heavy, heavy]]
Now create a transform $T_{\mathrm{s}}$ that relates pressure
and pressureb
to detect stormy weather,
let storm = VarStr "storm"
yes = ValStr "yes"; no = ValStr "no"
let tts = lltt [pressure,pressureb] [storm] [
[low, low, no],
[low, medium, no],
[low, high, yes],
[medium, low, no],
[medium, medium, no],
[medium, high, no],
[high, low, yes],
[high, medium, no],
[high, high, no]]
That is, a storm is where the two pressure variables are at opposite extremes.
Now we create a functional definition set decomposition $D$ which partitions the cartesian into stormy and normal weather. When it is stormy, the cloud is highly aligned with the rain,
let df = lldf [
[([], [tts]), ([(storm, no)], [ttcw, ttcp])],
[([], [tts]), ([(storm, yes)], [ttsc])]]
Consider the multiplication of the sample histogram and the decomposition,
rpln $ map (map (\(ss,bb) -> (ss, vars bb, size bb))) $ aa `dfmulll` df
"[({},{cloud,pressure,pressureb,rain,storm,wind},30 % 1),({(storm,no)},{cloud,cloud_and_pressure,cloud_and_wind,pressure,pressureb,rain,wind},20 % 1)]"
"[({},{cloud,pressure,pressureb,rain,storm,wind},30 % 1),({(storm,yes)},{cloud,pressure,pressureb,rain,storm_cloud,wind},10 % 1)]"
The first path is the normal weather slice,
let (_,aa1) = aa `dfmulll` df !! 0 !! 1
aa1 `ared` vv == hhaa hh1
True
If a query is in this slice the fud is just the fud $F = \{T_{\mathrm{cw}},T_{\mathrm{cp}}\}$ discussed in Functional definition sets.
The relative entropy and label alignment are different now because the substrate now contains the pressure2
variable,
rent (aa1 `tmul` (fftt (llff [ttcw, ttcp]))) (vvc `tmul` (fftt (llff [ttcw, ttcp])))
2.4392475869399846
tlalgn (fftt (llff [ttcw, ttcp])) aa1 [rain] - tlalgn (fftt (llff [ttcw, ttcp])) (ind aa1) [rain]
14.05877382277943
algn aa1
13.993685678223834
but the the label entropy is unchanged,
tlent (fftt (llff [ttcw, ttcp])) aa1 [rain]
8.018185525433372
The second path is the stormy weather slice,
let (_,aa2) = aa `dfmulll` df !! 1 !! 1
aa2 `ared` vv == hhaa hh2
True
If a query is in this slice the fud is just the fud of the transform of a rolled cloud
variable, $\{T_{\mathrm{sc}}\}$.
The relative entropy is
rent (aa2 `tmul` (fftt (llff [ttsc]))) (vvc `tmul` (fftt (llff [ttsc])))
9.317574090613334e-2
tlalgn (fftt (llff [ttsc])) aa2 [rain] - tlalgn (fftt (llff [ttsc])) (ind aa2) [rain]
1.9133297116444252
algn aa2
5.656670558662346
The label entropy is
tlent (fftt (llff [ttsc])) aa2 [rain]
3.8190850097688767
In the case of normal weather with medium pressure, heavy cloud and light winds, the forecast for rain
is heavy
,
let qq1 = hhaa $ llhh [pressure,pressureb,cloud,wind] [(1,[medium,medium,heavy,light])]
rpln $ map (fst. unzip) $ queryll qq1 df aa [rain]
"[{},{(storm,no)}]"
rpln $ aarr $ snd $ queryll qq1 df aa [rain] !! 0 !! 1
"({(rain,heavy)},1.0)"
In the case of stormy weather with low pressure, heavy cloud and light winds, the forecast for rain
is also heavy
,
let qq1s = hhaa $ llhh [pressure,pressureb,cloud,wind] [(1,[low,high,heavy,light])]
rpln $ map (fst. unzip) $ queryll qq1s df aa [rain]
"[{},{(storm,yes)}]"
rpln $ aarr $ snd $ queryll qq1s df aa [rain] !! 0 !! 1
"({(rain,heavy)},1.0)"
In the case of normal weather with low pressure, but no cloud and light winds, the prediction is ambiguous,
let qq2 = hhaa $ llhh [pressure,pressureb,cloud,wind] [(1,[low,medium,none,light])]
rpln $ map (fst. unzip) $ queryll qq2 df aa [rain]
"[{},{(storm,no)}]"
rpln $ aarr $ snd $ queryll qq2 df aa [rain] !! 0 !! 1
"({(rain,heavy)},0.2)"
"({(rain,light)},0.7)"
"({(rain,none)},0.1)"
In the case of stormy weather with low pressure, but no cloud and light winds, the prediction is ambiguous but wet,
let qq2s = hhaa $ llhh [pressure,pressureb,cloud,wind] [(1,[low,high,none,light])]
rpln $ map (fst. unzip) $ queryll qq2s df aa [rain]
"[{},{(storm,yes)}]"
rpln $ aarr $ snd $ queryll qq2s df aa [rain] !! 0 !! 1
"({(rain,heavy)},0.3333333333333333)"
"({(rain,light)},0.6666666666666666)"
In the case of normal weather with high pressure, no cloud and strong winds, the prediction is for dry,
let qq3 = hhaa $ llhh [pressure,pressureb,cloud,wind] [(1,[high,medium,none,strong])]
rpln $ map (fst. unzip) $ queryll qq3 df aa [rain]
"[{},{(storm,no)}]"
rpln $ aarr $ snd $ queryll qq3 df aa [rain] !! 0 !! 1
"({(rain,none)},1.0)"
In the case of stormy weather with high pressure, no cloud and strong winds, the prediction is for wet,
let qq3s = hhaa $ llhh [pressure,pressureb,cloud,wind] [(1,[high,low,none,strong])]
rpln $ map (fst. unzip) $ queryll qq3s df aa [rain]
"[{},{(storm,yes)}]"
rpln $ aarr $ snd $ queryll qq3s df aa [rain] !! 0 !! 1
"({(rain,heavy)},0.3333333333333333)"
"({(rain,light)},0.6666666666666666)"