Aligned Induction

States, histories and histograms

Python implementation of the Overview/States, histories and histograms

Sections

Variables, values and systems

States

Histories

Histograms

Independent Histograms

Example - a weather forecast

Variables, values and systems

The set of all variables is $\mathcal{V}$. The Variable type is usually defined with a String, an Integer or a pair of Variable,

data Variable = VarStr String | VarInt Integer | VarPair (Variable,Variable) | ...


For example,

suit = VarStr("suit")
rank = VarStr("rank")

vv = sset([suit, rank])

vv
# {rank, suit}


The set of all values is $\mathcal{W}$. The Value type is usually defined with a String, an Integer or a Double,

data Value  = ValStr String | ValInt Integer | ValDouble Double | ...


For example,

[hearts,clubs,diamonds,spades] = map(ValStr, ["hearts","clubs","diamonds","spades"])

wws = sset([hearts, clubs, diamonds, spades])

wws

[jack,queen,king,ace] = map(ValStr, ["J","Q","K","A"])

wwr = sset([jack,queen,king,ace] + [ValInt(i) for i in range(2,10+1)])

wwr
# {A, J, K, Q, 2, 3, 4, 5, 6, 7, 8, 9, 10}


A system $U \in \mathcal{V} \to \mathrm{P}(\mathcal{W})$ is a functional mapping between variables and non-empty sets of values, $\forall (v,W) \in U~(|W|>0)$. The System type is defined with a Map.Map from Variable to a set of Value,

newtype System = System (Map.Map Variable (Set.Set Value))


A System can be constructed from a list of pairs of Variable and Value sets,

listsSystem :: [(Variable, Set.Set Value)] -> Maybe System
systemsList :: System -> [(Variable, Set.Set Value)]


For example,

uu = listsSystem([(suit,wws), (rank,wwr)])

uu
# {(rank, {A, J, K, Q, 2, 3, 4, 5, 6, 7, 8, 9, 10}), (suit, {clubs, diamonds, hearts, spades})}

rpln(systemsList(uu))
# (rank, {A, J, K, Q, 2, 3, 4, 5, 6, 7, 8, 9, 10})
# (suit, {clubs, diamonds, hearts, spades})


The Variable set accessor is

systemsVars :: System -> Set.Set Variable


For example,

uvars = systemsVars

uvars(uu)
# {rank, suit}


The Value set accessor is

systemsVarsSetValue :: System -> Variable -> Maybe (Set.Set Value)


For example,

uat  = systemsVarsSetValue

uat(uu,suit)


The valency of a variable $v$ is the cardinality of its values, $|U_v|$,

len(uat(uu,suit))
# 4

len(uat(uu,rank))
# 13


The volume of a set of variables in a system $V \subseteq \mathrm{vars}(U)$ is the product of the valencies, $\prod_{v \in V} |U_v| \geq 1$,

systemsSetVarsVolume :: System -> Set.Set Variable -> Maybe Integer


For example

vol = systemsSetVarsVolume

vol(uu,vv)
# 52

vol(uu,sset([suit]))
# 4

vol(uu,sset([rank]))
# 13


The volume of an empty set of variables is defined as $1$,

vol(uu,sset())
# 1


A regular system $Uâ€™$ of dimension $n$ cardinal variables $\{1 \ldots n\}$ each of valency $d$ cardinal values $\{1 \ldots d\}$ is constructed

systemRegular :: Integer -> Integer -> Maybe System


For example,

sysreg = systemRegular

uu1 = sysreg(3,2)

vol(uu1, uvars(uu1))
# 9


States

The set of states is the set of value valued functions of variable, $\mathcal{S} = \mathcal{V} \to \mathcal{W}$. The State type is defined with a Map.Map from Variable to Value,

newtype State = State (Map.Map Variable Value)


A State can be constructed from a list of pairs of Variable and Value,

listsState :: [(Variable, Value)] -> State
statesList :: State -> [(Variable, Value)]


The variables of a state $S \in \mathcal{S}$ is the function domain, $\mathrm{vars}(S) := \mathrm{dom}(S)$,

statesVars :: State -> Set.Set Variable


For example,

llss = listsState
ssll = statesList

ss

rpln(ssll(ss))
# (rank, A)

svars = statesSetVar

svars(ss)
# {rank, suit}


The Value accessor is

statesVarsValue :: State -> Variable -> Maybe Value


For example,

sat = statesVarsValue

sat(ss,suit)


The empty state, $\{\}$, has no variables,

stateEmpty :: State


For example,

svars(stateEmpty())
# {}


The state, $S$, is in a system $U$ if (i) the variables of the state are variables of the system, $\mathrm{vars}(S) \subseteq \mathrm{vars}(U)$, and (ii) the value of each variable in the state is in the system, $\forall v \in \mathrm{vars}(S)~(S_v \in U_v)$,

systemsStatesIs :: System -> State -> Bool


For example,

systemsStatesIs(uu,ss)
# True

svars(ss) <= uvars(uu)
# True

sat(ss,suit) in uat(uu,suit)
# True

sat(ss,rank) in uat(uu,rank)
# True

systemsStatesIs(uu1,ss)
# False


Given a set of variables in a system $V \subseteq \mathrm{vars}(U)$, the cartesian set of all possible states is $\prod_{v \in V} ({v} \times U_v)$,

systemsSetVarsSetStateCartesian :: System -> Set.Set Variable -> Maybe (Set.Set State)


which has cardinality equal to the volume $\prod_{v \in V} |U_v|$,

cart = systemsSetVarsSetStateCartesian

rpln(cart(uu,vv))
# {(rank, A), (suit, clubs)}
# {(rank, A), (suit, diamonds)}
# {(rank, A), (suit, hearts)}
# {(rank, J), (suit, clubs)}
# {(rank, J), (suit, diamonds)}
# ...
# {(rank, 9), (suit, hearts)}
# {(rank, 10), (suit, clubs)}
# {(rank, 10), (suit, diamonds)}
# {(rank, 10), (suit, hearts)}

len(cart(uu, vv))
# 52

vol(uu, vv)
# 52


The variables $V = \mathrm{vars}(S)$ of a state $S$ may be reduced to a given subset $K \subseteq V$ by taking the subset of the variable-value pairs, $S~\%~K := \{(v,u) :(v,u) \in S,~v \in K\}$

setVarsStatesStateFiltered :: Set.Set Variable -> State -> State


For example,

def sred(ss,vv):

sred(ss,svars(ss))

sred(ss,sset())
# {}

sred(ss,sset([suit]))

sred(ss,sset([rank]))
# {(rank, A)}


A set of states $Q \subset \mathcal{S}$ in the same variables $\forall S \in Q~(\mathrm{vars}(S)=V)$ may be split into a subset of its variables $K \subseteq V$ and the complement $V \setminus K$, $\mathrm{split}(K,Q) = \{(S~\%~K,~S~\%~(V \setminus K)) :S \in Q\}$

setVarsSetStatesSplit :: Set.Set Variable -> Set.Set State -> Set.Set (State,State)


For example,

ssplit = setVarsSetStatesSplit

rpln(ssplit(sset([suit]),cart(uu,vv)))
# ({(suit, clubs)}, {(rank, A)})
# ({(suit, clubs)}, {(rank, J)})
# ({(suit, clubs)}, {(rank, K)})
# ({(suit, clubs)}, {(rank, Q)})
# ({(suit, clubs)}, {(rank, 2)})
# ...


Two states $S,T \in \mathcal{S}$ are said to join if their union is also a state, $S \cup T \in \mathcal{S}$,

pairStatesIsJoin :: State -> State -> Bool
pairStatesUnionLeft :: State -> State -> State


For example,

sjoin = pairStatesUnionLeft

colour = VarStr("colour")
red = ValStr("red")
black = ValStr("black")

pairStatesIsJoin(ss,tt)
# True

sjoin(ss,tt)
# {(colour, black), (rank, A), (suit, spades)}

qq = llss([(suit,hearts),(colour,red)])

pairStatesIsJoin(ss,qq)
# False

pairStatesIsJoin(ss,rr)
# False

pairStatesIsJoin(ss,ss)
# True


Histories

The set of event identifiers is the universal set $\mathcal{X}$. The Id type is usually defined with a String, an Integer, a pair of Id or a null,

data Id = IdStr String | IdInt Integer | IdPair (Id,Id) | IdNull | ...


An event $(x,S)$ is a pair of an event identifier and a state, $(x,S) \in \mathcal{X} \times \mathcal{S}$. A history $H$ is a state valued function of event identifiers, $H \in \mathcal{X} \to \mathcal{S}$, such that all of the states of its events share the same set of variables, $\forall (x,S),(y,T) \in H~(\mathrm{vars}(S)=\mathrm{vars}(T))$. The set of histories is denoted $\mathcal{H} \subset \mathcal{X} \to \mathcal{S}$. The History type is defined with a Map.Map from Id to State,

newtype History = History (Map.Map Id State)


A History can be constructed from a list of pairs of Id and State,

listsHistory :: [(Id, State)] -> Maybe History
historyToList :: History -> [(Id, State)]


For example, if a deck of cards happens to be dealt in alphanumeric order the history is

suit = VarStr("suit")
rank = VarStr("rank")
vv = sset([suit, rank])
wws = sset([hearts, clubs, diamonds, spades])
[jack,queen,king,ace] = map(ValStr, ["J","Q","K","A"])
wwr = sset([jack,queen,king,ace] + [ValInt(i) for i in range(2,10+1)])
uu = listsSystem([(suit,wws), (rank,wwr)])

llhh = listsHistory
hhll = historiesList

hh = llhh([(IdInt(i+1),ss) for (i,ss) in enumerate(cart(uu, vv))])

rpln(hhll(hh))
# (1, {(rank, A), (suit, clubs)})
# (2, {(rank, A), (suit, diamonds)})
# (3, {(rank, A), (suit, hearts)})
# (4, {(rank, A), (suit, spades)})
# (5, {(rank, J), (suit, clubs)})
# (6, {(rank, J), (suit, diamonds)})
# ...
# (47, {(rank, 9), (suit, hearts)})
# (48, {(rank, 9), (suit, spades)})
# (49, {(rank, 10), (suit, clubs)})
# (50, {(rank, 10), (suit, diamonds)})
# (51, {(rank, 10), (suit, hearts)})
# (52, {(rank, 10), (suit, spades)})


The set of variables of a history is the set of the variables of any of the events of the history, $\mathrm{vars}(H) = \mathrm{vars}(S)$ where $(x,S) \in H$,

historiesSetVar :: History -> Set.Set Variable


For example,

hvars = historiesSetVar

hvars(hh)
# {rank, suit}


The inverse of a history, $H^{-1}$, is called the classification. So a classification is an event identifier set valued function of state, $H^{-1} \in \mathcal{S} \to \mathrm{P}(\mathcal{X})$. The Classification type is defined with a Map.Map from State to a set of Id,

newtype Classification = Classification (Map.Map State (Set.Set Id))


A Classification can be constructed from a History and vice-versa,

historiesClassification :: History -> Classification
classificationsHistory :: Classification -> History


For example,

hhgg = historiesClassification
gghh = classificationsHistory
ggll = classificationsList

rpln(ggll(hhgg(hh)))
# ({(rank, A), (suit, clubs)}, {1})
# ({(rank, A), (suit, diamonds)}, {2})
# ({(rank, A), (suit, hearts)}, {3})
# ({(rank, A), (suit, spades)}, {4})
# ({(rank, J), (suit, clubs)}, {5})
# ({(rank, J), (suit, diamonds)}, {6})
# ...
# ({(rank, 9), (suit, hearts)}, {47})
# ({(rank, 9), (suit, spades)}, {48})
# ({(rank, 10), (suit, clubs)}, {49})
# ({(rank, 10), (suit, diamonds)}, {50})
# ({(rank, 10), (suit, hearts)}, {51})
# ({(rank, 10), (suit, spades)}, {52})

gghh(hhgg(hh)) == hh
# True


The reduction of a history is the reduction of its events, $H\%V := \{(x,S\%V) : (x,S) \in H\}$,

setVarsHistoriesReduce :: Set.Set Variable -> History -> History


For example,

def hred(hh,vv):
return setVarsHistoriesReduce(vv,hh)

rpln(hhll(hred(hh,sset([suit]))))
# (1, {(suit, clubs)})
# (2, {(suit, diamonds)})
# (3, {(suit, hearts)})
# (5, {(suit, clubs)})
# (6, {(suit, diamonds)})
# ...
# (47, {(suit, hearts)})
# (49, {(suit, clubs)})
# (50, {(suit, diamonds)})
# (51, {(suit, hearts)})

rpln(ggll(hhgg(hred(hh,sset([suit])))))
# ({(suit, clubs)}, {1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49})
# ({(suit, diamonds)}, {2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46, 50})
# ({(suit, hearts)}, {3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51})
# ({(suit, spades)}, {4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52})

rpln(ggll(hhgg(hred(hh,sset([rank])))))
# ({(rank, A)}, {1, 2, 3, 4})
# ({(rank, J)}, {5, 6, 7, 8})
# ({(rank, K)}, {9, 10, 11, 12})
# ({(rank, Q)}, {13, 14, 15, 16})
# ({(rank, 2)}, {17, 18, 19, 20})
# ({(rank, 3)}, {21, 22, 23, 24})
# ({(rank, 4)}, {25, 26, 27, 28})
# ({(rank, 5)}, {29, 30, 31, 32})
# ({(rank, 6)}, {33, 34, 35, 36})
# ({(rank, 7)}, {37, 38, 39, 40})
# ({(rank, 8)}, {41, 42, 43, 44})
# ({(rank, 9)}, {45, 46, 47, 48})
# ({(rank, 10)}, {49, 50, 51, 52})


The size of a history is its cardinality,

historiesSize :: History -> Integer


For example,

hsize = historiesSize

hsize(hh)
# 52

hsize(hh) == len(hhll(hh))
# True


The addition operation of histories is defined as the disjoint union of the events if both histories have the same variables, $H_1 + H_2~:=~\{((x,\cdot),S) : (x,S) \in H_1\}~\cup~\{((\cdot,y),T) : (y,T) \in H_2\}$ where $\mathrm{vars}(H_1) = \mathrm{vars}(H_2)$,

pairHistoriesAdd :: History -> History -> Maybe History


For example,

hadd = pairHistoriesAdd

# ((1,_), {(rank, A), (suit, clubs)})
# ((2,_), {(rank, A), (suit, diamonds)})
# ((3,_), {(rank, A), (suit, hearts)})
# ((4,_), {(rank, A), (suit, spades)})
# ((5,_), {(rank, J), (suit, clubs)})
# ...
# ((50,_), {(rank, 10), (suit, diamonds)})
# ((51,_), {(rank, 10), (suit, hearts)})
# ((52,_), {(rank, 10), (suit, spades)})
# ((_,1), {(rank, A), (suit, clubs)})
# ((_,2), {(rank, A), (suit, diamonds)})
# ((_,3), {(rank, A), (suit, hearts)})
# ...
# ((_,47), {(rank, 9), (suit, hearts)})
# ((_,48), {(rank, 9), (suit, spades)})
# ((_,49), {(rank, 10), (suit, clubs)})
# ((_,50), {(rank, 10), (suit, diamonds)})
# ((_,51), {(rank, 10), (suit, hearts)})
# ((_,52), {(rank, 10), (suit, spades)})

# 104


The size of the sum equals the sum of the sizes, $|H_1 + H_2| = |H_1| + |H_2|$,

hsize(hadd(hh,hh)) == hsize(hh) + hsize(hh)
# True


The multiplication operation of histories is defined as the product of the events where the states join, $\begin{eqnarray} H_1 * H_2 &:=& \{((x,y),S \cup T) : (x,S) \in H_1,~(y,T) \in H_2,\\ & &\hspace{5em}\forall v \in \mathrm{vars}(S) \cap \mathrm{vars}(T)~(S_v = T_v)\} \end{eqnarray}$

pairHistoriesMultiply :: History -> History -> History


For example,

hmul = pairHistoriesMultiply

rpln(hhll(hmul(hh,hh)))
# ((1,1), {(rank, A), (suit, clubs)})
# ((2,2), {(rank, A), (suit, diamonds)})
# ((3,3), {(rank, A), (suit, hearts)})
# ((4,4), {(rank, A), (suit, spades)})
# ((5,5), {(rank, J), (suit, clubs)})
# ((6,6), {(rank, J), (suit, diamonds)})
# ...
# ((47,47), {(rank, 9), (suit, hearts)})
# ((48,48), {(rank, 9), (suit, spades)})
# ((49,49), {(rank, 10), (suit, clubs)})
# ((50,50), {(rank, 10), (suit, diamonds)})
# ((51,51), {(rank, 10), (suit, hearts)})
# ((52,52), {(rank, 10), (suit, spades)})

hsize(hmul(hh,hh))
# 52

coin = VarStr("coin")
tails = ValStr("tails")

gg = llhh([(IdInt(1), llss([(coin,heads)])), (IdInt(2), llss([(coin,tails)]))])

rpln(hhll(gg))
# (2, {(coin, tails)})

rpln(hhll(hmul(hh,gg)))
# ((1,1), {(coin, heads), (rank, A), (suit, clubs)})
# ((1,2), {(coin, tails), (rank, A), (suit, clubs)})
# ((2,1), {(coin, heads), (rank, A), (suit, diamonds)})
# ((2,2), {(coin, tails), (rank, A), (suit, diamonds)})
# ((3,1), {(coin, heads), (rank, A), (suit, hearts)})
# ((3,2), {(coin, tails), (rank, A), (suit, hearts)})
# ...
# ((50,1), {(coin, heads), (rank, 10), (suit, diamonds)})
# ((50,2), {(coin, tails), (rank, 10), (suit, diamonds)})
# ((51,1), {(coin, heads), (rank, 10), (suit, hearts)})
# ((51,2), {(coin, tails), (rank, 10), (suit, hearts)})
# ((52,2), {(coin, tails), (rank, 10), (suit, spades)})

hsize(hmul(hh,gg))
# 104


The size of the product equals the product of the sizes if the variables are disjoint, $\mathrm{vars}(H_1) \cap \mathrm{vars}(H_2) = \emptyset \implies |H_1 * H_2| = |H_1| \times |H_2|$,

hsize(hmul(hh,gg)) == hsize(hh) * hsize(gg)
# True


The variables of the product is the union of the variables if the size is non-zero, $H_1 * H_2 \neq \emptyset \implies \mathrm{vars}(H_1 * H_2) = \mathrm{vars}(H_1) \cup \mathrm{vars}(H_2)$,

hvars(hmul(hh,gg)) == hvars(hh) | hvars(gg)
# True


Histograms

The set of all histograms $\mathcal{A}$ is a subset of the positive rational valued functions of states, $\mathcal{A} \subset \mathcal{S} \to \mathbf{Q}_{\geq 0}$, such that each state of each histogram has the same set of variables, $\forall A \in \mathcal{A}~\forall S,T \in \mathrm{dom}(A)~(\mathrm{vars}(S)=\mathrm{vars}(T))$. The Histogram type is defined with a Map.Map from State to Rational,

newtype Histogram = Histogram (Map.Map State Rational)


A Histogram can be constructed from a list of pairs of State and Rational,

listsHistogram :: [(State, Rational)] -> Maybe Histogram
histogramsList :: Histogram -> [(State, Rational)]


For example, the histogram of a deck of cards is

suit = VarStr("suit")
rank = VarStr("rank")
vv = sset([suit, rank])
wws = sset([hearts, clubs, diamonds, spades])
[jack,queen,king,ace] = map(ValStr, ["J","Q","K","A"])
wwr = sset([jack,queen,king,ace] + [ValInt(i) for i in range(2,10+1)])
uu = listsSystem([(suit,wws), (rank,wwr)])

llaa = listsHistogram
aall = histogramsList

aa = llaa([(ss,ratio(1,1)) for ss in 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)


The set of variables of a histogram $A \in \mathcal{A}$ is the set of the variables of any of the elements of the histogram, $\mathrm{vars}(A) = \mathrm{vars}(S)$ where $(S,q) \in A$,

histogramsSetVar :: Histogram -> Set.Set Variable


For example,

vars = histogramsSetVar

vars(aa)
# {rank, suit}


Given a variable map, a histogram may be reframed,

histogramsMapVarsFrame :: Histogram -> Map.Map Variable Variable -> Maybe Histogram


For example,

def reframe(aa,mm):
return histogramsMapVarsFrame(aa,sdict(mm))

rpln(aall(reframe(aa,[(suit, VarStr("S")), (rank, VarStr("R"))])))
# ({(R, A), (S, clubs)}, 1 % 1)
# ({(R, A), (S, diamonds)}, 1 % 1)
# ({(R, A), (S, hearts)}, 1 % 1)
# ({(R, A), (S, spades)}, 1 % 1)
# ({(R, J), (S, clubs)}, 1 % 1)
# ({(R, J), (S, diamonds)}, 1 % 1)
# ...
# ({(R, 9), (S, hearts)}, 1 % 1)
# ({(R, 9), (S, spades)}, 1 % 1)
# ({(R, 10), (S, clubs)}, 1 % 1)
# ({(R, 10), (S, diamonds)}, 1 % 1)
# ({(R, 10), (S, hearts)}, 1 % 1)
# ({(R, 10), (S, spades)}, 1 % 1)

vars(reframe(aa,[(suit, VarStr("S")), (rank, VarStr("R"))]))
# {R, S}


The dimension of a histogram is the cardinality of its variables, $|\mathrm{vars}(A)|$,

len(vars(aa))
# 2


The states of a histogram is the domain, $A^{\mathrm{S}} := \mathrm{dom}(A)$,

histogramsStates :: Histogram -> Set.Set State


For example,

states = histogramsStates

rpln(states(aa))
# {(rank, A), (suit, clubs)}
# {(rank, A), (suit, diamonds)}
# {(rank, A), (suit, hearts)}
# {(rank, J), (suit, clubs)}
# {(rank, J), (suit, diamonds)}
# ...
# {(rank, 9), (suit, hearts)}
# {(rank, 10), (suit, clubs)}
# {(rank, 10), (suit, diamonds)}
# {(rank, 10), (suit, hearts)}


The count accessor is

histogramsStatesCount :: Histogram -> State -> Maybe Rational


For example,

aat = histogramsStatesCount

ss

aat(aa,ss)
# 1 % 1


The size of a histogram is the sum of the counts, $\mathrm{size}(A) := \mathrm{sum}(A)$,

histogramsSize :: Histogram -> Rational


For example,

size = histogramsSize

size(aa)
# 52 % 1


If the size is non-zero the normalised histogram has a size of one, $\mathrm{size}(A) > 0 \implies \mathrm{size}(\hat{A}) = 1$,

histogramsResize :: Rational -> Histogram -> Maybe Histogram


For example,

def norm(aa):
return histogramsResize(1,aa)

rpln(aall(norm(aa)))
# ({(rank, A), (suit, clubs)}, 1 % 52)
# ({(rank, A), (suit, diamonds)}, 1 % 52)
# ({(rank, A), (suit, hearts)}, 1 % 52)
# ({(rank, A), (suit, spades)}, 1 % 52)
# ({(rank, J), (suit, clubs)}, 1 % 52)
# ({(rank, J), (suit, diamonds)}, 1 % 52)
# ...
# ({(rank, 9), (suit, hearts)}, 1 % 52)
# ({(rank, 9), (suit, spades)}, 1 % 52)
# ({(rank, 10), (suit, clubs)}, 1 % 52)
# ({(rank, 10), (suit, diamonds)}, 1 % 52)
# ({(rank, 10), (suit, hearts)}, 1 % 52)
# ({(rank, 10), (suit, spades)}, 1 % 52)

size(norm(aa))
# 1 % 1


The volume of a histogram $A$ of variables $V$ in a system $U$ is the volume of the variables, $\prod_{v \in V} |U_v|$,

vol(uu,vars(aa))
# 52


A histogram with no variables is called a scalar. The scalar of size $z$ is $\{(\emptyset,z)\}$. Define $\mathrm{scalar}(z) := \{(\emptyset,z)\}$.

histogramScalar :: Rational -> Maybe Histogram


For example,

scalar = histogramScalar

scalar(52)
# {({}, 52 % 1)}

vars(scalar(52))
# {}

scalar(52) == llaa([(stateEmpty(),52)])
# True


A singleton is a histogram with only one state, $\{(S,z)\}$,

histogramsIsSingleton :: Histogram -> Bool
histogramSingleton :: State -> Rational -> Maybe Histogram


For example,

single = histogramSingleton

rr = llss([(suit,hearts),(rank,queen)])

bb =  llaa([(ss,1)])

bb
# {({(rank, A), (suit, spades)}, 1 % 1)}

histogramsIsSingleton(bb)
# True

bb == single(ss,1)
# True

cc =  llaa([(ss,1),(rr,1)])

cc
# {({(rank, A), (suit, spades)}, 1 % 1), ({(rank, Q), (suit, hearts)}, 1 % 1)}

histogramsIsSingleton(cc)
# False

histogramsIsSingleton(scalar(1))
# True


A uniform histogram $A$ has unique non-zero count, $|\{c : (S,c) \in A,~c>0\}|=1$,

histogramsIsUniform :: Histogram -> Bool


For example,

histogramsIsUniform(aa)
# True

histogramsIsUniform(bb)
# True

histogramsIsUniform(cc)
# True

histogramsIsUniform(scalar(1))
# True

dd = llaa([(ss,1),(rr,2)])

dd
# {({(rank, A), (suit, spades)}, 1 % 1), ({(rank, Q), (suit, hearts)}, 2 % 1)}

histogramsIsUniform(dd)
# False


The set of integral histograms is the subset of histograms which have integal counts $\mathcal{A}_{\mathrm{i}} = \mathcal{A}~\cap~(\mathcal{S} \to \mathbf{N})$,

histogramsIsIntegral :: Histogram -> Bool


For example,

list(map(histogramsIsIntegral,[aa,bb,cc,dd,scalar(1)]))
# [True, True, True, True, True]

histogramsIsIntegral(norm(aa))
# False


A unit histogram is a special case of an integral histogram in which all its counts equal one, $\mathrm{ran}(A)=\{1\}$,

histogramsIsUnit :: Histogram -> Bool


For example,

list(map(histogramsIsUnit,[aa,bb,cc,dd,scalar(1),norm(aa)]))
# [True, True, True, False, True, False]


The size of a unit histogram equals its cardinality, $\mathrm{size}(A)=|A|$,

list(map(size,[aa,bb,cc,scalar(1)]))
# [52 % 1, 1 % 1, 2 % 1, 1 % 1]

def alen(aa):
return len(aall(aa))

list(map(alen,[aa,bb,cc,scalar(1)]))
# [52, 1, 2, 1]


A set of states $Q \subset \mathcal{S}$ in the same variables may be promoted to a unit histogram, $Q^{\mathrm{U}} := Q \times {1} \in \mathcal{A}_{\mathrm{i}}$,

setStatesHistogramUnit :: Set.Set State -> Maybe Histogram


For example,

unit = setStatesHistogramUnit

aa == unit(cart(uu,vv))
# True

cc == unit(sset([ss,rr]))
# True


The effective states of a histogram are those where the count is non-zero. A histogram may be trimmed to its effective states, $\{(S,c) : (S,c) \in A,~c>0\}$,

histogramsTrim :: Histogram -> Histogram


For example,

trim = histogramsTrim

rpln(aall(trim(llaa([(ss,3),(rr,0)]))))
# ({(rank, A), (suit, spades)}, 3 % 1)

rpln(aall(trim(llaa([(ss,3),(rr,5)]))))
# ({(rank, A), (suit, spades)}, 3 % 1)
# ({(rank, Q), (suit, hearts)}, 5 % 1)

trim(llaa([(ss,0),(rr,0)])) == histogramEmpty()
# True


The unit effective histogram of a histogram is the unit histogram of the effective states, $A^{\mathrm{F}} := \{(S,1) : (S,c) \in A,~c>0\} \in \mathcal{A}_{\mathrm{i}}$,

histogramsEffective :: Histogram -> Histogram


For example,

eff = histogramsEffective

ee = llaa([(ss,3),(rr,0)])

ee
# {({(rank, A), (suit, spades)}, 3 % 1), ({(rank, Q), (suit, hearts)}, 0 % 1)}

eff(ee)
# {({(rank, A), (suit, spades)}, 1 % 1)}

[xx == eff(xx) for xx in [aa,bb,cc,dd,scalar(1),norm(aa),ee]]
# [True, True, True, False, True, False, False]


Given a system $U$ define the cartesian histogram of the set of variables $V$ as $V^{\mathrm{C}} := \big(\prod_{v \in V} ({v} \times U_v)\big) \times {1} \in \mathcal{A}_{\mathrm{i}}$,

vvc = unit(cart(uu,vv))

aa == vvc
# True


The size of the cartesian histogram equals its cardinality which is the volume of the variables, $\mathrm{size}(V^{\mathrm{C}})=|V^{\mathrm{C}}| = \prod_{v \in V} |U_v|$,

size(vvc)
# 52 % 1

len(aall(vvc))
# 52

vol(uu,vv)
# 52


The unit effective histogram is a subset of the cartesian histogram of its variables, $A^{\mathrm{F}} \subseteq V^{\mathrm{C}}$, where $V = \mathrm{vars}(A)$,

def aaqq(aa):
return sset(aall(aa))

[aaqq(eff(xx)) <= aaqq(vvc) for xx in [aa,bb,cc,dd,scalar(1),norm(aa),ee]]
# [True, True, True, True, True, True, True]


A partition $P$ is a partition of the cartesian states, $P \in \mathrm{B}(V^{\mathrm{CS}})$. The partition is a set of disjoint components, $\forall C,D \in P~(C \neq D \implies C \cap D = \emptyset)$, that union to equal the cartesian states, $\bigcup P = V^{\mathrm{CS}}$. The Component type is a set of State,

type Component = Set.Set State


The Partition type is a set of Component,

newtype Partition = Partition (Set.Set Component)


A Partition can be constructed from a set of Component,

setComponentsPartition :: Set.Set Component -> Maybe Partition
partitionsSetComponent :: Partition -> Set.Set Component


For example,

qqpp = setComponentsPartition
ppqq = partitionsSetComponent

c = sset(list(states(vvc))[0:13])

len(c)
# 13

d = sset(list(states(vvc))[13:])

len(d)
# 39

len(c & d) == 0
# True

c | d == states(vvc)
# True

pp = qqpp(sset([c,d]))

all([len(c & d) == 0 for c in ppqq(pp) for d in ppqq(pp) if c != d])
# True

bigcup =  setSetsUnion

all([c | d == bigcup(ppqq(pp)) for c in ppqq(pp) for d in ppqq(pp) if c != d])
# True


The unary partition is $\{V^{\mathrm{CS}}\}$,

systemsSetVarsPartitionUnary :: System -> Set.Set Variable -> Maybe Partition


For example,

unary = systemsSetVarsPartitionUnary

ppqq(unary(uu,vv)) == sset([states(vvc)])
# True


The self partition is $V^{\mathrm{CS}\{\}} = \{\{S\} : S \in V^{\mathrm{CS}}\}$,

systemsSetVarsPartitionSelf :: System -> Set.Set Variable -> Maybe Partition


For example,

self = systemsSetVarsPartitionSelf

ppqq(self(uu,vv)) == sset([sset([x]) for x in states(vvc)])
# True


A partition variable $P \in \mathrm{vars}(U)$ in a system $U$ is such that its set of values equals its set of components, $U_P = P$. So the valency of a partition variable is the cardinality of the components, $|U_P| = |P|$. The Variable type can be constructed with a Partition,

data Variable = ... | VarPartition Partition | ...


Similarly, the Value type can be constructed with a Component,

data Value = ... | ValComponent Component | ...


For example,

uu1 = listsSystem([(VarPartition(pp), sset([ValComponent(c),ValComponent(d)]))])

len(uat(uu1,VarPartition(pp)))
# 2

len(uat(uu1,VarPartition(pp))) == len(ppqq(pp))
# True


A regular histogram $Aâ€™$ of variables $Vâ€™$ in system $Uâ€™$ has unique valency of its variables, $|\{|Uâ€™_v| : v \in Vâ€™\}|=1$. The volume of a regular histogram is $d^n = |{Vâ€™}^{\mathrm{C}}| = \prod_{v \in Vâ€™} |Uâ€™_v|$, where valency $d$ is such that $\{d\} = \{|Uâ€™_v| : v \in Vâ€™\}$ and dimension $n = |Vâ€™|$. For example,

sysreg = systemRegular

uu1 = sysreg(3,2)

uu1
# {(1, {1, 2, 3}), (2, {1, 2, 3})}

vol(uu1,uvars(uu1))
# 9

aa1 = llaa([(llss([(VarInt(1), ValInt(1)),(VarInt(2), ValInt(1))]), 1)])

aa1
# {({(1, 1), (2, 1)}, 1 % 1)}

vars(aa1)
# {1, 2}

vol(uu1,vars(aa1))
# 9

d = len(uat(uu1,VarInt(1)))

n = len(vars(aa1))

d**n
# 9


A regular cartesian histogram of cardinal variables $\{1 \ldots n\}$ and cardinal values $\{1 \ldots d\}$ is constructed,

histogramRegularCartesian :: Integer -> Integer -> Maybe Histogram


For example,

regcart = histogramRegularCartesian

rpln(aall(regcart(3,2)))
# ({(1, 1), (2, 1)}, 1 % 1)
# ({(1, 1), (2, 2)}, 1 % 1)
# ({(1, 1), (2, 3)}, 1 % 1)
# ({(1, 2), (2, 1)}, 1 % 1)
# ({(1, 2), (2, 2)}, 1 % 1)
# ({(1, 2), (2, 3)}, 1 % 1)
# ({(1, 3), (2, 1)}, 1 % 1)
# ({(1, 3), (2, 2)}, 1 % 1)
# ({(1, 3), (2, 3)}, 1 % 1)

uu1 = sysreg(3,2)

regcart(3,2) == unit(cart(uu1,(uvars(uu1))))
# True


A regular unit singleton histogram of cardinal variables $\{1 \ldots n\}$ and cardinal values $\{1 \ldots d\}$ is constructed,

histogramRegularUnitSingleton :: Integer -> Integer -> Maybe Histogram


For example,

regsing = histogramRegularUnitSingleton

rpln(aall(regsing(3,2)))
# ({(1, 1), (2, 1)}, 1 % 1)


A regular unit diagonal histogram of cardinal variables $\{1 \ldots n\}$ and cardinal values $\{1 \ldots d\}$ is constructed,

histogramRegularUnitDiagonal :: Integer -> Integer -> Maybe Histogram


For example,

regdiag = histogramRegularUnitDiagonal

rpln(aall(regdiag(3,2)))
# ({(1, 1), (2, 1)}, 1 % 1)
# ({(1, 2), (2, 2)}, 1 % 1)
# ({(1, 3), (2, 3)}, 1 % 1)


A histogram may be reframed to a list of cardinal variables by transposition,

def cdtp(aa,ll):
return reframe(aa, zip(list(vars(aa)), map(VarInt,ll)))

rpln(aall(cdtp(regcart(2,2),[3,4])))
# ({(3, 1), (4, 1)}, 1 % 1)
# ({(3, 1), (4, 2)}, 1 % 1)
# ({(3, 2), (4, 1)}, 1 % 1)
# ({(3, 2), (4, 2)}, 1 % 1)

rpln(aall(cdtp(regsing(2,2),[3,2])))
# ({(2, 1), (3, 1)}, 1 % 1)


A unit histogram of cardinal variables and cardinal values may be constructed from a list of states which are in turn constructed from lists of integers,

def cdaa(ll):
return llaa([(llss([(VarInt(i), ValInt(j)) for i,j in enumerate(ss,1)]),1) for ss in ll])

cdaa([[1,1],[1,2],[2,1],[2,2]]) == regcart(2,2)
# True

cdaa([[1,1,1]]) == regsing(2,3)
# True


The counts of the integral histogram $A \in \mathcal{A}_{\mathrm{i}}$ of a history $H \in \mathcal{H}$ are the cardinalities of the event identifier components of its classification, $A = \mathrm{histogram}(H)$ where $\mathrm{histogram}(H) := \{(S,|X|) : (S,X) \in H^{-1}\}$,

historiesHistogram :: History -> Histogram


For example,

llhh = listsHistory
hhll = historiesList

hhaa = historiesHistogram

hh = llhh([(IdInt(i),ss) for i,ss in enumerate(cart(uu,vv),1)])

aa = llaa([(ss,1) for ss in cart(uu,vv)])

hhaa(hh) == aa
# True

hhgg = historiesClassification
gghh = classificationsHistory
ggll = classificationsList

gghh(hhgg(hh)) == hh
# True

llaa([(ss, len(xx)) for (ss,xx) in ggll(hhgg(hh))]) == aa
# True


Given an integral histogram $A \in \mathcal{A}_{\mathrm{i}}$, a history $H$ can be constructed by creating an event identifier for each element of each component of the classification, $H = \mathrm{history}(A)$ where $\mathrm{history}(A) := \bigcup \{\{((S,i),S) : i \in \{1 \ldots q\}\} : (S,q) \in A\}$,

histogramsHistory :: Histogram -> Maybe History


For example,

aahh = histogramsHistory

hhaa(aahh(aa)) == aa
# True

rpln(hhll(aahh(regdiag(3,2))))
# (({(1, 1), (2, 1)}, 1), {(1, 1), (2, 1)})
# (({(1, 2), (2, 2)}, 1), {(1, 2), (2, 2)})
# (({(1, 3), (2, 3)}, 1), {(1, 3), (2, 3)})

rpln(hhll(aahh(mul(regdiag(3,2),scalar(3)))))
# (({(1, 1), (2, 1)}, 1), {(1, 1), (2, 1)})
# (({(1, 1), (2, 1)}, 2), {(1, 1), (2, 1)})
# (({(1, 1), (2, 1)}, 3), {(1, 1), (2, 1)})
# (({(1, 2), (2, 2)}, 1), {(1, 2), (2, 2)})
# (({(1, 2), (2, 2)}, 2), {(1, 2), (2, 2)})
# (({(1, 2), (2, 2)}, 3), {(1, 2), (2, 2)})
# (({(1, 3), (2, 3)}, 1), {(1, 3), (2, 3)})
# (({(1, 3), (2, 3)}, 2), {(1, 3), (2, 3)})
# (({(1, 3), (2, 3)}, 3), {(1, 3), (2, 3)})


Note that multiplication of histograms is described below.

A sub-histogram $B$ of a histogram $A$ is such that the effective states of $B$ are a subset of the effective states of $A$ and the counts of $B$ are less than or equal to those of $A$, $B \leq A := B^{\mathrm{FS}} \subseteq A^{\mathrm{FS}}~\wedge~\forall S \in B^{\mathrm{FS}}~(B_S \leq A_S)$,

pairHistogramsLeq :: Histogram -> Histogram -> Bool


For example,

leq = pairHistogramsLeq

bb
# {({(rank, A), (suit, spades)}, 1 % 1)}

leq(bb,aa)
# True

cc =  llaa([(ss,1),(rr,1)])

[leq(xx,aa) for xx in [aa,bb,cc,dd,scalar(1),norm(aa),ee]]
# [True, True, True, False, False, True, False]


The reduction of a histogram is the reduction of its states, adding the counts where two different states reduce to the same state, $A\%V := \{(R, \sum (c : (T, c) \in A,~T \supseteq R)) : R \in \{S\%V : S \in A^{\mathrm{S}}\}\}$

setVarsHistogramsReduce :: Set.Set Variable -> Histogram -> Histogram


For example,

def ared(aa,vv):
return setVarsHistogramsReduce(vv,aa)

rpln(aall(ared(aa,sset([suit]))))
# ({(suit, clubs)}, 13 % 1)
# ({(suit, diamonds)}, 13 % 1)
# ({(suit, hearts)}, 13 % 1)
# ({(suit, spades)}, 13 % 1)

rpln(aall(ared(aa,sset([rank]))))
# ({(rank, A)}, 4 % 1)
# ({(rank, J)}, 4 % 1)
# ({(rank, K)}, 4 % 1)
# ({(rank, Q)}, 4 % 1)
# ({(rank, 2)}, 4 % 1)
# ({(rank, 3)}, 4 % 1)
# ({(rank, 4)}, 4 % 1)
# ({(rank, 5)}, 4 % 1)
# ({(rank, 6)}, 4 % 1)
# ({(rank, 7)}, 4 % 1)
# ({(rank, 8)}, 4 % 1)
# ({(rank, 9)}, 4 % 1)
# ({(rank, 10)}, 4 % 1)

rpln(aall(ared(aa,sset())))
# ({}, 52 % 1)

ared(aa,vars(aa)) == aa
# True


The reduction to the empty set is a scalar, $A\%\emptyset = \{(\emptyset,z)\}$, where $z = \mathrm{size}(A)$,

ared(aa,sset()) == scalar(size(aa))
# True


Reduction leaves the size of a histogram unchanged,

list(map(size,[aa, ared(aa,sset([suit])), ared(aa,sset([rank])), ared(aa,sset())]))
# [52 % 1, 52 % 1, 52 % 1, 52 % 1]


The histogram of a reduction of a history equals the reduction of the histogram of the history, $\mathrm{histogram}(H~\%~V) = \mathrm{histogram}(H)~\%~V$

vs = sset([suit])

hhaa(hred(hh,vs)) == ared(hhaa(hh),vs)
# True


The addition of histograms $A$ and $B$ is defined, $\begin{eqnarray} A + B &:=& \{ (S, c) : (S,c) \in A,~S \notin B^{\mathrm{S}} \}~\cup\\ & & \{ (S, c + d) : (S,c) \in A,~(T,d) \in B,~S = T \}~\cup \\ & & \{ (T, d) : (T,d) \in B,~T \notin A^{\mathrm{S}} \} \end{eqnarray}$ where $\mathrm{vars}(A) = \mathrm{vars}(B)$.

pairHistogramsAdd :: Histogram -> Histogram -> Maybe Histogram


For example,

add = pairHistogramsAdd

bb
# {({(rank, A), (suit, spades)}, 1 % 1)}

cc
# {({(rank, A), (suit, spades)}, 1 % 1), ({(rank, Q), (suit, hearts)}, 1 % 1)}

dd
# {({(rank, A), (suit, spades)}, 1 % 1), ({(rank, Q), (suit, hearts)}, 2 % 1)}

# {({(rank, A), (suit, spades)}, 2 % 1), ({(rank, Q), (suit, hearts)}, 1 % 1)}

# {({(rank, A), (suit, spades)}, 2 % 1), ({(rank, Q), (suit, hearts)}, 3 % 1)}

# {({(rank, A), (suit, spades)}, 3 % 1), ({(rank, Q), (suit, hearts)}, 3 % 1)}


The sizes add, $\mathrm{size}(A+B) = \mathrm{size}(A) + \mathrm{size}(B)$,

size(bb) + size(cc) + size(dd) == size(add(bb,add(cc,dd)))
# True


The histogram of an addition of histories equals the addition of the histograms of the histories, $\mathrm{histogram}(H_1+H_2) = \mathrm{histogram}(H_1) + \mathrm{histogram}(H_2)$

hh = aahh(aa)

gg = aahh(bb)

# True


The multiplication of histograms $A$ and $B$ is the product of the counts where the states join, $A*B := \{ (S \cup T, cd) : (S,c) \in A,~(T,d) \in B,~\forall v \in \mathrm{vars}(S) \cap \mathrm{vars}(T)~(S_v = T_v)\}$

pairHistogramsMultiply :: Histogram -> Histogram -> Histogram


For example,

mul = pairHistogramsMultiply

colour = VarStr("colour")
red = ValStr("red")
black = ValStr("black")

bb = llaa([(llss([(suit, u),(colour, w)]),1) for (u,w) in [(hearts, red), (clubs, black), (diamonds, red), (spades, black)]])

rpln(aall(bb))
# ({(colour, black), (suit, clubs)}, 1 % 1)
# ({(colour, black), (suit, spades)}, 1 % 1)
# ({(colour, red), (suit, diamonds)}, 1 % 1)
# ({(colour, red), (suit, hearts)}, 1 % 1)

rpln(aall(mul(aa,bb)))
# ({(colour, black), (rank, A), (suit, clubs)}, 1 % 1)
# ({(colour, black), (rank, A), (suit, spades)}, 1 % 1)
# ({(colour, black), (rank, J), (suit, clubs)}, 1 % 1)
# ({(colour, black), (rank, J), (suit, spades)}, 1 % 1)
# ({(colour, black), (rank, K), (suit, clubs)}, 1 % 1)
# ({(colour, black), (rank, K), (suit, spades)}, 1 % 1)
# ...
# ({(colour, red), (rank, 8), (suit, diamonds)}, 1 % 1)
# ({(colour, red), (rank, 8), (suit, hearts)}, 1 % 1)
# ({(colour, red), (rank, 9), (suit, diamonds)}, 1 % 1)
# ({(colour, red), (rank, 9), (suit, hearts)}, 1 % 1)
# ({(colour, red), (rank, 10), (suit, diamonds)}, 1 % 1)
# ({(colour, red), (rank, 10), (suit, hearts)}, 1 % 1)

rpln(aall(ared(mul(aa,bb),sset([rank,colour]))))
# ({(colour, black), (rank, A)}, 2 % 1)
# ({(colour, black), (rank, J)}, 2 % 1)
# ...
# ({(colour, black), (rank, 9)}, 2 % 1)
# ({(colour, black), (rank, 10)}, 2 % 1)
# ({(colour, red), (rank, A)}, 2 % 1)
# ({(colour, red), (rank, J)}, 2 % 1)
# ...
# ({(colour, red), (rank, 9)}, 2 % 1)
# ({(colour, red), (rank, 10)}, 2 % 1)

rpln(aall(ared(mul(aa,bb),sset([colour]))))
# ({(colour, black)}, 26 % 1)
# ({(colour, red)}, 26 % 1)


If the variables are disjoint, the sizes multiply, $\mathrm{vars}(A) \cap \mathrm{vars}(B) = \emptyset \implies \mathrm{size}(A*B) = \mathrm{size}(A) \times \mathrm{size}(B)$,

coin = VarStr("coin")
tails = ValStr("tails")

rpln(aall(cc))
# ({(coin, heads)}, 1 % 1)
# ({(coin, tails)}, 1 % 1)

rpln(aall(mul(aa,cc)))
# ({(coin, heads), (rank, A), (suit, clubs)}, 1 % 1)
# ({(coin, heads), (rank, A), (suit, diamonds)}, 1 % 1)
# ({(coin, heads), (rank, A), (suit, hearts)}, 1 % 1)
# ({(coin, heads), (rank, J), (suit, clubs)}, 1 % 1)
# ({(coin, heads), (rank, J), (suit, diamonds)}, 1 % 1)
# ...
# ({(coin, heads), (rank, 9), (suit, hearts)}, 1 % 1)
# ({(coin, heads), (rank, 10), (suit, clubs)}, 1 % 1)
# ({(coin, heads), (rank, 10), (suit, diamonds)}, 1 % 1)
# ({(coin, heads), (rank, 10), (suit, hearts)}, 1 % 1)
# ({(coin, tails), (rank, A), (suit, clubs)}, 1 % 1)
# ({(coin, tails), (rank, A), (suit, diamonds)}, 1 % 1)
# ({(coin, tails), (rank, A), (suit, hearts)}, 1 % 1)
# ({(coin, tails), (rank, A), (suit, spades)}, 1 % 1)
# ({(coin, tails), (rank, J), (suit, clubs)}, 1 % 1)
# ({(coin, tails), (rank, J), (suit, diamonds)}, 1 % 1)
# ...
# ({(coin, tails), (rank, 9), (suit, hearts)}, 1 % 1)
# ({(coin, tails), (rank, 9), (suit, spades)}, 1 % 1)
# ({(coin, tails), (rank, 10), (suit, clubs)}, 1 % 1)
# ({(coin, tails), (rank, 10), (suit, diamonds)}, 1 % 1)
# ({(coin, tails), (rank, 10), (suit, hearts)}, 1 % 1)
# ({(coin, tails), (rank, 10), (suit, spades)}, 1 % 1)

size(aa)
# 52 % 1

size(cc)
# 2 % 1

size(mul(aa,cc)) == size(aa) * size(cc)
# True

rpln(aall(ared(mul(aa,cc),sset([coin]))))
# ({(coin, heads)}, 52 % 1)
# ({(coin, tails)}, 52 % 1)


Multiplication by a scalar scales the size, $\mathrm{size}(\mathrm{scalar}(z)*A) = z \times \mathrm{size}(A)$,

size(scalar(2))
# 2 % 1

size(mul(scalar(2),aa))
# 104 % 1


The histogram of a multiplication of histories equals the multiplication of the histograms of the histories, $\mathrm{histogram}(H_1*H_2) = \mathrm{histogram}(H_1) * \mathrm{histogram}(H_2)$

hh = aahh(aa)

gg = aahh(bb)

hhaa(hmul(hh,gg)) == mul(hhaa(hh),hhaa(gg))
# True


The reciprocal of a histogram is $1/A := \{(S, 1/c) : (S, c) \in A,~c>0\}$,

histogramsReciprocal :: Histogram -> Histogram


Define histogram division as $B/A := B*(1/A)$,

pairHistogramsDivide :: Histogram -> Histogram -> Histogram


For example,

recip = histogramsReciprocal
divide = pairHistogramsDivide

scalar(ratio(1,2)) == recip(scalar(2))
# True

divide(aa,scalar(52)) == norm(aa)
# True

scalar(ratio(1,2)) == divide(scalar(1),scalar(2))
# True


A histogram $A$ is causal in a subset of its variables $K \subset V$ if the reduction of the effective states to the subset, $K$, is functionally related to the reduction to the complement, $V \setminus K$, $\{(S~\%~K,~S~\%~(V \setminus K)) : S \in A^{\mathrm{FS}}\} \in K^{\mathrm{CS}} \to (V \setminus K)^{\mathrm{CS}}$ or $\mathrm{split}(K,A^{\mathrm{FS}}) \in K^{\mathrm{CS}} \to (V \setminus K)^{\mathrm{CS}}$

histogramsIsCausal :: Histogram -> Bool


In the example, the histogram of the deck of cards, $A$, is cartesian and not causal,

iscausal = histogramsIsCausal

iscausal(aa)
# False


The histogram of the colours of the suits, $B$, however, is causal from suit to colour,

rpln(aall(bb))
# ({(colour, black), (suit, clubs)}, 1 % 1)
# ({(colour, black), (suit, spades)}, 1 % 1)
# ({(colour, red), (suit, diamonds)}, 1 % 1)
# ({(colour, red), (suit, hearts)}, 1 % 1)

iscausal(bb)
# True

rpln(ssplit(sset([suit]),states(eff(bb))))
# ({(suit, clubs)}, {(colour, black)})
# ({(suit, diamonds)}, {(colour, red)})
# ({(suit, hearts)}, {(colour, red)})

rpln(ssplit(sset([colour]),states(eff(bb))))
# ({(colour, black)}, {(suit, clubs)})
# ({(colour, red)}, {(suit, diamonds)})
# ({(colour, red)}, {(suit, hearts)})

iscausal(mul(aa,bb))
# True

rpln(ssplit(sset([suit,rank]),states(eff(mul(aa,bb)))))
# ({(rank, A), (suit, clubs)}, {(colour, black)})
# ({(rank, A), (suit, diamonds)}, {(colour, red)})
# ({(rank, A), (suit, hearts)}, {(colour, red)})
# ({(rank, A), (suit, spades)}, {(colour, black)})
# ({(rank, J), (suit, clubs)}, {(colour, black)})
# ({(rank, J), (suit, diamonds)}, {(colour, red)})
# ...
# ({(rank, 9), (suit, hearts)}, {(colour, red)})
# ({(rank, 9), (suit, spades)}, {(colour, black)})
# ({(rank, 10), (suit, clubs)}, {(colour, black)})
# ({(rank, 10), (suit, diamonds)}, {(colour, red)})
# ({(rank, 10), (suit, hearts)}, {(colour, red)})
# ({(rank, 10), (suit, spades)}, {(colour, black)})


A histogram $A$ is diagonalised if no pair of effective states shares any value, $\forall S,T \in A^{\mathrm{FS}}~(S \neq T \implies S \cap T = \emptyset)$,

histogramsIsDiagonal :: Histogram -> Bool


For example,

isdiag = histogramsIsDiagonal

isdiag(aa)
# False

isdiag(bb)
# False

isdiag(mul(aa,bb))
# False


In a diagonalised histogram the causality is bijective or equational, $\forall u,w \in V~(\{(S\%{u},S\%{w}) : S \in A^{\mathrm{FS}}\}~\in~\{u\}^{\mathrm{CS}} \leftrightarrow \{w\}^{\mathrm{CS}})$

saturation = VarStr("saturation")
white = ValStr("white")
grey = ValStr("grey")
black = ValStr("black")

dd = llaa([(llss([(colour, u),(saturation, w)]),1) for (u,w) in [(red, grey), (black, black)]])

rpln(aall(dd))
# ({(colour, black), (saturation, black)}, 1 % 1)
# ({(colour, red), (saturation, grey)}, 1 % 1)

isdiag(dd)
# True


Similarly for a regular unit histograms,

rpln(aall(regdiag(3,2)))
# ({(1, 1), (2, 1)}, 1 % 1)
# ({(1, 2), (2, 2)}, 1 % 1)
# ({(1, 3), (2, 3)}, 1 % 1)

iscausal(regdiag(3,2))
# True

isdiag(regdiag(3,2))
# True

iscausal(regcart(3,2))
# False

isdiag(regcart(3,2))
# False

iscausal(regsing(3,2))
# True

isdiag(regsing(3,2))
# True

# False

# False

# True

# True


Given some slice state $R \in K^{\mathrm{CS}}$, where $K \subset V$ and $V = \mathrm{vars}(A)$, the slice histogram, $A * \{R\}^{\mathrm{U}} \subset A$, is said to be contingent on the incident slice state,

rr = llss([(suit,spades)])

rpln(aall(mul(aa,unit(sset([rr])))))
# ({(rank, A), (suit, spades)}, 1 % 1)
# ({(rank, J), (suit, spades)}, 1 % 1)
# ({(rank, K), (suit, spades)}, 1 % 1)
# ({(rank, Q), (suit, spades)}, 1 % 1)
# ({(rank, 2), (suit, spades)}, 1 % 1)
# ({(rank, 3), (suit, spades)}, 1 % 1)
# ({(rank, 4), (suit, spades)}, 1 % 1)
# ({(rank, 5), (suit, spades)}, 1 % 1)
# ({(rank, 6), (suit, spades)}, 1 % 1)
# ({(rank, 7), (suit, spades)}, 1 % 1)
# ({(rank, 8), (suit, spades)}, 1 % 1)
# ({(rank, 9), (suit, spades)}, 1 % 1)
# ({(rank, 10), (suit, spades)}, 1 % 1)


For example, if the slice histogram is diagonalised, $\mathrm{diagonal}(A * \{R\}^{\mathrm{U}}~\%~(V \setminus K))$, then the histogram, $A$, is said to be contingently diagonalised,

ee = add(mul(cdaa([[1]]),cdtp(regdiag(2,2),[2,3])),mul(cdaa([[2]]),cdtp(regcart(2,2),[2,3])))

rpln(aall(ee))
# ({(1, 1), (2, 1), (3, 1)}, 1 % 1)
# ({(1, 1), (2, 2), (3, 2)}, 1 % 1)
# ({(1, 2), (2, 1), (3, 1)}, 1 % 1)
# ({(1, 2), (2, 1), (3, 2)}, 1 % 1)
# ({(1, 2), (2, 2), (3, 1)}, 1 % 1)
# ({(1, 2), (2, 2), (3, 2)}, 1 % 1)

rpln(aall(mul(ee,cdaa([[1]]))))
# ({(1, 1), (2, 1), (3, 1)}, 1 % 1)
# ({(1, 1), (2, 2), (3, 2)}, 1 % 1)

vk = sset([VarInt(2),VarInt(3)])

isdiag(ared(mul(ee,cdaa([[1]])),vk))
# True

rpln(aall(mul(ee,cdaa([[2]]))))
# ({(1, 2), (2, 1), (3, 1)}, 1 % 1)
# ({(1, 2), (2, 1), (3, 2)}, 1 % 1)
# ({(1, 2), (2, 2), (3, 1)}, 1 % 1)
# ({(1, 2), (2, 2), (3, 2)}, 1 % 1)

isdiag(ared(mul(ee,cdaa([[2]])),vk))
# False


Independent Histograms

The perimeters of a histogram $A \in \mathcal{A}$ is the set of its reductions to each of its variables, $\{A\%\{w\} : w \in V\}$, where $V = \mathrm{vars}(A)$,

rpln(aall(ared(aa,sset([suit]))))
# ({(suit, clubs)}, 13 % 1)
# ({(suit, diamonds)}, 13 % 1)
# ({(suit, hearts)}, 13 % 1)
# ({(suit, spades)}, 13 % 1)

rpln(aall(ared(aa,sset([rank]))))
# ({(rank, A)}, 4 % 1)
# ({(rank, J)}, 4 % 1)
# ({(rank, K)}, 4 % 1)
# ({(rank, Q)}, 4 % 1)
# ({(rank, 2)}, 4 % 1)
# ({(rank, 3)}, 4 % 1)
# ({(rank, 4)}, 4 % 1)
# ({(rank, 5)}, 4 % 1)
# ({(rank, 6)}, 4 % 1)
# ({(rank, 7)}, 4 % 1)
# ({(rank, 8)}, 4 % 1)
# ({(rank, 9)}, 4 % 1)
# ({(rank, 10)}, 4 % 1)


The independent of a histogram is the product of the normalised perimeters scaled to the size, $A^{\mathrm{X}} := Z * \prod_{w \in V} \hat{A}\%\{w\}$ where $z = \mathrm{size}(A)$ and $Z = \mathrm{scalar}(z) = A\%\emptyset$,

histogramsIndependent :: Histogram -> Histogram


For example,

ind = histogramsIndependent

ind(aa) == mul(mul(scalar(size(aa)),ared(norm(aa),sset([suit]))),ared(norm(aa),sset([rank])))
# True


The size is unchanged, $\mathrm{size}(A^{\mathrm{X}}) = \mathrm{size}(A)$,

size(ind(aa)) == size(aa)
# True


A histogram is said to be independent if it equals its independent, $A = A^{\mathrm{X}}$,

aa == ind(aa)
# True

regdiag(2,2) == ind(regdiag(2,2))
# False


Scalar histograms are independent, $\{(\emptyset,z)\} = \{(\emptyset,z)\}^{\mathrm{X}}$,

scalar(52) == ind(scalar(52))
# True


Singleton histograms, $|A^{\mathrm{F}}| = 1$, are independent, $\{(S,z)\} = \{(S,z)\}^{\mathrm{X}}$,

regsing(2,2) == ind(regsing(2,2))
# True


If the histogram is mono-variate, $|V|=1$, then it is independent $A = A \% \{w\} = A^{\mathrm{X}}$ where $\{w\} = V$,

ared(regdiag(2,2),sset([VarInt(1)])) == ind(ared(regdiag(2,2),sset([VarInt(1)])))
# True


Cartesian histograms are independent, $V^{\mathrm{C}} = V^{\mathrm{CX}}$,

regcart(2,2) == ind(regcart(2,2))
# True

aa == ind(aa)
# True


The independent of a uniform fully diagonalised histogram equals the sized cartesian,

norm(ind(regdiag(2,2))) == norm(regcart(2,2))
# True


A completely effective pluri-variate independent histogram, $A^{\mathrm{XF}} = V^{\mathrm{C}}$ where $|V|>1$, for which all of the variables are pluri-valent, $\forall w \in V~(|U_w| > 1)$, must be non-causal,

iscausal(ind(regdiag(2,2)))
# False

iscausal(regdiag(2,2))
# True


Example - a weather forecast

Some of the concepts above regarding histories and histograms can be demonstrated with a sample of some weather measurements. Let system $U$ consist of four variables, (i) pressure, having values low, medium and high, (ii) cloud, having values none, light and heavy, (iii) wind, having values none, light and strong, and (iv) rain, having values none, light and heavy,

[pressure,cloud,wind,rain] = map(VarStr,["pressure","cloud","wind","rain"])

[low,medium,high,none,light,heavy,strong] = map(ValStr,["low","medium","high","none","light","heavy","strong"])

def lluu(ll):
return listsSystem([(v,sset(ww)) for (v,ww) in ll])

uu = lluu([
(pressure, [low,medium,high]),
(cloud,    [none,light,heavy]),
(wind,     [none,light,strong]),
(rain,     [none,light,heavy])])

uu
# {(cloud, {heavy, light, none}), (pressure, {high, low, medium}), (rain, {heavy, light, none}), (wind, {light, none, strong})}

uvars(uu)
# {cloud, pressure, rain, wind}

vv = uvars(uu)

vol(uu,vv)
# 81

3**4
# 81


Now let history $H$ be constructed from the following sample,

event pressure cloud wind rain
1 high none none none
2 medium light none light
3 high none light none
4 low heavy strong heavy
5 low none light light
6 medium none light light
7 low heavy light heavy
8 high none light none
9 medium light strong heavy
10 medium light light light
11 high light light heavy
12 medium none none none
13 medium light none none
14 high light strong light
15 medium none light light
16 low heavy strong heavy
17 low heavy light heavy
18 high none none none
19 low light none light
20 high none none none
def llhh(vv,ev):
return listsHistory([(IdInt(i), llss(zip(vv,ll))) for (i,ll) in ev])

hh = llhh([pressure,cloud,wind,rain],[
(1,[high,none,none,none]),
(2,[medium,light,none,light]),
(3,[high,none,light,none]),
(4,[low,heavy,strong,heavy]),
(5,[low,none,light,light]),
(6,[medium,none,light,light]),
(7,[low,heavy,light,heavy]),
(8,[high,none,light,none]),
(9,[medium,light,strong,heavy]),
(10,[medium,light,light,light]),
(11,[high,light,light,heavy]),
(12,[medium,none,none,none]),
(13,[medium,light,none,none]),
(14,[high,light,strong,light]),
(15,[medium,none,light,light]),
(16,[low,heavy,strong,heavy]),
(17,[low,heavy,light,heavy]),
(18,[high,none,none,none]),
(19,[low,light,none,light]),
(20,[high,none,none,none])])

rpln(hhll(hh))
# (1, {(cloud, none), (pressure, high), (rain, none), (wind, none)})
# (2, {(cloud, light), (pressure, medium), (rain, light), (wind, none)})
# (3, {(cloud, none), (pressure, high), (rain, none), (wind, light)})
# (4, {(cloud, heavy), (pressure, low), (rain, heavy), (wind, strong)})
# (5, {(cloud, none), (pressure, low), (rain, light), (wind, light)})
# (6, {(cloud, none), (pressure, medium), (rain, light), (wind, light)})
# (7, {(cloud, heavy), (pressure, low), (rain, heavy), (wind, light)})
# (8, {(cloud, none), (pressure, high), (rain, none), (wind, light)})
# (9, {(cloud, light), (pressure, medium), (rain, heavy), (wind, strong)})
# (10, {(cloud, light), (pressure, medium), (rain, light), (wind, light)})
# (11, {(cloud, light), (pressure, high), (rain, heavy), (wind, light)})
# (12, {(cloud, none), (pressure, medium), (rain, none), (wind, none)})
# (13, {(cloud, light), (pressure, medium), (rain, none), (wind, none)})
# (14, {(cloud, light), (pressure, high), (rain, light), (wind, strong)})
# (15, {(cloud, none), (pressure, medium), (rain, light), (wind, light)})
# (16, {(cloud, heavy), (pressure, low), (rain, heavy), (wind, strong)})
# (17, {(cloud, heavy), (pressure, low), (rain, heavy), (wind, light)})
# (18, {(cloud, none), (pressure, high), (rain, none), (wind, none)})
# (19, {(cloud, light), (pressure, low), (rain, light), (wind, none)})
# (20, {(cloud, none), (pressure, high), (rain, none), (wind, none)})

hvars(hh)
# {cloud, pressure, rain, wind}

hsize(hh)
# 20


The event identifiers are classified,

hhgg = historiesClassification
gghh = classificationsHistory
ggll = classificationsList

rpln(ggll(hhgg(hh)))
# ({(cloud, heavy), (pressure, low), (rain, heavy), (wind, light)}, {7, 17})
# ({(cloud, heavy), (pressure, low), (rain, heavy), (wind, strong)}, {4, 16})
# ({(cloud, light), (pressure, high), (rain, heavy), (wind, light)}, {11})
# ({(cloud, light), (pressure, high), (rain, light), (wind, strong)}, {14})
# ({(cloud, light), (pressure, low), (rain, light), (wind, none)}, {19})
# ({(cloud, light), (pressure, medium), (rain, heavy), (wind, strong)}, {9})
# ({(cloud, light), (pressure, medium), (rain, light), (wind, light)}, {10})
# ({(cloud, light), (pressure, medium), (rain, light), (wind, none)}, {2})
# ({(cloud, light), (pressure, medium), (rain, none), (wind, none)}, {13})
# ({(cloud, none), (pressure, high), (rain, none), (wind, light)}, {3, 8})
# ({(cloud, none), (pressure, high), (rain, none), (wind, none)}, {1, 18, 20})
# ({(cloud, none), (pressure, low), (rain, light), (wind, light)}, {5})
# ({(cloud, none), (pressure, medium), (rain, light), (wind, light)}, {6, 15})
# ({(cloud, none), (pressure, medium), (rain, none), (wind, none)}, {12})


The history can be reduced to a subset of the variables,

def hred(hh,vv):
return setVarsHistoriesReduce(sset(vv),hh)

rpln(hhll(hred(hh,[pressure,rain])))
# (1, {(pressure, high), (rain, none)})
# (2, {(pressure, medium), (rain, light)})
# (3, {(pressure, high), (rain, none)})
# ...
# (18, {(pressure, high), (rain, none)})
# (19, {(pressure, low), (rain, light)})
# (20, {(pressure, high), (rain, none)})

rpln(ggll(hhgg(hred(hh,[pressure,rain]))))
# ({(pressure, high), (rain, heavy)}, {11})
# ({(pressure, high), (rain, light)}, {14})
# ({(pressure, high), (rain, none)}, {1, 3, 8, 18, 20})
# ({(pressure, low), (rain, heavy)}, {4, 7, 16, 17})
# ({(pressure, low), (rain, light)}, {5, 19})
# ({(pressure, medium), (rain, heavy)}, {9})
# ({(pressure, medium), (rain, light)}, {2, 6, 10, 15})
# ({(pressure, medium), (rain, none)}, {12, 13})


Let the sample histogram be constructed from the history, $A = \mathrm{histogram}(H)$,

aa = hhaa(hh)

rpln(aall(aa))
# ({(cloud, heavy), (pressure, low), (rain, heavy), (wind, light)}, 2 % 1)
# ({(cloud, heavy), (pressure, low), (rain, heavy), (wind, strong)}, 2 % 1)
# ({(cloud, light), (pressure, high), (rain, heavy), (wind, light)}, 1 % 1)
# ({(cloud, light), (pressure, high), (rain, light), (wind, strong)}, 1 % 1)
# ({(cloud, light), (pressure, low), (rain, light), (wind, none)}, 1 % 1)
# ({(cloud, light), (pressure, medium), (rain, heavy), (wind, strong)}, 1 % 1)
# ({(cloud, light), (pressure, medium), (rain, light), (wind, light)}, 1 % 1)
# ({(cloud, light), (pressure, medium), (rain, light), (wind, none)}, 1 % 1)
# ({(cloud, light), (pressure, medium), (rain, none), (wind, none)}, 1 % 1)
# ({(cloud, none), (pressure, high), (rain, none), (wind, light)}, 2 % 1)
# ({(cloud, none), (pressure, high), (rain, none), (wind, none)}, 3 % 1)
# ({(cloud, none), (pressure, low), (rain, light), (wind, light)}, 1 % 1)
# ({(cloud, none), (pressure, medium), (rain, light), (wind, light)}, 2 % 1)
# ({(cloud, none), (pressure, medium), (rain, none), (wind, none)}, 1 % 1)

vars(aa)
# {cloud, pressure, rain, wind}

size(aa)
# 20 % 1

histogramsIsUniform(aa)
# False

histogramsIsIntegral(aa)
# True

histogramsIsUnit(aa)
# False

size(unit(cart(uu,vv)))
# 81 % 1

leq(eff(aa),unit(cart(uu,vv)))
# True

rpln(aall(norm(aa)))
# ({(cloud, heavy), (pressure, low), (rain, heavy), (wind, light)}, 1 % 10)
# ({(cloud, heavy), (pressure, low), (rain, heavy), (wind, strong)}, 1 % 10)
# ({(cloud, light), (pressure, high), (rain, heavy), (wind, light)}, 1 % 20)
# ({(cloud, light), (pressure, high), (rain, light), (wind, strong)}, 1 % 20)
# ({(cloud, light), (pressure, low), (rain, light), (wind, none)}, 1 % 20)
# ({(cloud, light), (pressure, medium), (rain, heavy), (wind, strong)}, 1 % 20)
# ({(cloud, light), (pressure, medium), (rain, light), (wind, light)}, 1 % 20)
# ({(cloud, light), (pressure, medium), (rain, light), (wind, none)}, 1 % 20)
# ({(cloud, light), (pressure, medium), (rain, none), (wind, none)}, 1 % 20)
# ({(cloud, none), (pressure, high), (rain, none), (wind, light)}, 1 % 10)
# ({(cloud, none), (pressure, high), (rain, none), (wind, none)}, 3 % 20)
# ({(cloud, none), (pressure, low), (rain, light), (wind, light)}, 1 % 20)
# ({(cloud, none), (pressure, medium), (rain, light), (wind, light)}, 1 % 10)
# ({(cloud, none), (pressure, medium), (rain, none), (wind, none)}, 1 % 20)


Now consider the relationships (a) between pressure and rain,

histogramsIsDiagonal(aa)
# False

histogramsIsCausal(aa)
# False

def red(aa,ll):
return setVarsHistogramsReduce(sset(ll),aa)

def ssplit(ll,aa):

rpln(aall(red(aa,[pressure,rain])))
# ({(pressure, high), (rain, heavy)}, 1 % 1)
# ({(pressure, high), (rain, light)}, 1 % 1)
# ({(pressure, high), (rain, none)}, 5 % 1)
# ({(pressure, low), (rain, heavy)}, 4 % 1)
# ({(pressure, low), (rain, light)}, 2 % 1)
# ({(pressure, medium), (rain, heavy)}, 1 % 1)
# ({(pressure, medium), (rain, light)}, 4 % 1)
# ({(pressure, medium), (rain, none)}, 2 % 1)

rpln(ssplit([pressure],red(aa,[pressure,rain])))
# ({(pressure, high)}, {(rain, heavy)})
# ({(pressure, high)}, {(rain, light)})
# ({(pressure, high)}, {(rain, none)})
# ({(pressure, low)}, {(rain, heavy)})
# ({(pressure, low)}, {(rain, light)})
# ({(pressure, medium)}, {(rain, heavy)})
# ({(pressure, medium)}, {(rain, light)})
# ({(pressure, medium)}, {(rain, none)})

histogramsIsCausal(red(aa,[pressure,rain]))
# False


and (b) between (i) cloud and wind, and (ii) rain,

rpln(aall(red(aa,[cloud,wind,rain])))
# ({(cloud, heavy), (rain, heavy), (wind, light)}, 2 % 1)
# ({(cloud, heavy), (rain, heavy), (wind, strong)}, 2 % 1)
# ({(cloud, light), (rain, heavy), (wind, light)}, 1 % 1)
# ({(cloud, light), (rain, heavy), (wind, strong)}, 1 % 1)
# ({(cloud, light), (rain, light), (wind, light)}, 1 % 1)
# ({(cloud, light), (rain, light), (wind, none)}, 2 % 1)
# ({(cloud, light), (rain, light), (wind, strong)}, 1 % 1)
# ({(cloud, light), (rain, none), (wind, none)}, 1 % 1)
# ({(cloud, none), (rain, light), (wind, light)}, 3 % 1)
# ({(cloud, none), (rain, none), (wind, light)}, 2 % 1)
# ({(cloud, none), (rain, none), (wind, none)}, 4 % 1)

rpln(ssplit([cloud,wind],red(aa,[cloud,wind,rain])))
# ({(cloud, heavy), (wind, light)}, {(rain, heavy)})
# ({(cloud, heavy), (wind, strong)}, {(rain, heavy)})
# ({(cloud, light), (wind, light)}, {(rain, heavy)})
# ({(cloud, light), (wind, light)}, {(rain, light)})
# ({(cloud, light), (wind, none)}, {(rain, light)})
# ({(cloud, light), (wind, none)}, {(rain, none)})
# ({(cloud, light), (wind, strong)}, {(rain, heavy)})
# ({(cloud, light), (wind, strong)}, {(rain, light)})
# ({(cloud, none), (wind, light)}, {(rain, light)})
# ({(cloud, none), (wind, light)}, {(rain, none)})
# ({(cloud, none), (wind, none)}, {(rain, none)})

histogramsIsCausal(red(aa,[cloud,wind,rain]))
# False


Although the sample histogram is neither diagonal nor causal, it is not independent, $A \neq A^{\mathrm{X}}$,

aa == ind(aa)
# False


The perimeters are

rpln(aall(red(aa,[pressure])))
# ({(pressure, high)}, 7 % 1)
# ({(pressure, low)}, 6 % 1)
# ({(pressure, medium)}, 7 % 1)

rpln(aall(red(aa,[cloud])))
# ({(cloud, heavy)}, 4 % 1)
# ({(cloud, light)}, 7 % 1)
# ({(cloud, none)}, 9 % 1)

rpln(aall(red(aa,[wind])))
# ({(wind, light)}, 9 % 1)
# ({(wind, none)}, 7 % 1)
# ({(wind, strong)}, 4 % 1)

rpln(aall(red(aa,[rain])))
# ({(rain, heavy)}, 6 % 1)
# ({(rain, light)}, 7 % 1)
# ({(rain, none)}, 7 % 1)


The sample independent is

rpln(aall(ind(aa)))
# ({(cloud, heavy), (pressure, high), (rain, heavy), (wind, light)}, 189 % 1000)
# ({(cloud, heavy), (pressure, high), (rain, heavy), (wind, none)}, 147 % 1000)
# ({(cloud, heavy), (pressure, high), (rain, heavy), (wind, strong)}, 21 % 250)
# ({(cloud, heavy), (pressure, high), (rain, light), (wind, light)}, 441 % 2000)
# ...
# ({(cloud, none), (pressure, medium), (rain, light), (wind, strong)}, 441 % 2000)
# ({(cloud, none), (pressure, medium), (rain, none), (wind, light)}, 3969 % 8000)
# ({(cloud, none), (pressure, medium), (rain, none), (wind, none)}, 3087 % 8000)
# ({(cloud, none), (pressure, medium), (rain, none), (wind, strong)}, 441 % 2000)


The weather forecast example continues in Entropy and alignment.

top