Framework

Haskell implementation of fast Practicable Inducers/Framework

Sections

Histogram and HistogramRepa

History and HistoryRepa

Transform and TransformRepa

Histogram and HistogramRepa

Histograms are defined in the overview in section ‘States, histories and histograms’ P8 and in the paper in section ‘Histograms’ P94. The discussion of the Haskell implementation of Histograms is in the Haskell implementation of the Overview.

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}$. The Histogram type is defined in module Alignment with a Map.Map from State to Rational,

newtype Histogram = Histogram (Map.Map State Rational)

This set-theoretic implementation is a poset binary map representation discussed in the paper in section ‘Computation of histograms’ P405. The definition of binary maps is in appendix ‘Binary maps’ P1164.

In the case where the histogram $A \in \mathcal{A}$ is complete, $A^{\mathrm{S}} = V^{\mathrm{CS}}$ where $V = \mathrm{vars}(A)$, the binary map histogram representation has accessor time complexity of $\ln v$ where volume $v = |V^{\mathrm{C}}|$. In the case of a regular histogram of valency $\{d\} = \{|U_w| : w \in V\}$, the time complexity is $n \ln d$, where dimension $n = |V|$.

An array histogram representation (P402) is implemented as an array of counts, $\mathbf{Q}_{\geq 0}^v$, of size $v$. If indexing is implemented with an ordered list state representation the accessor time complexity is $n$. The array histogram representation may require less time, but the array must be of cardinality equal to the volume, and so its space complexity is $v$, which may be greater than that of the effective binary map histogram representation, $|A^{\mathrm{F}}| \ln |A^{\mathrm{F}}|$.

For the cases where the volume is practicable, the module AlignmentRepa defines type HistogramRepa in terms of the multi-dimensional shape polymorphic parallel array which is defined in the repa library,

data HistogramRepa = HistogramRepa {
  histogramRepasVectorVar :: !(V.Vector Variable),
  histogramRepasMapVarInt :: Map.Map Variable Int,
  histogramRepasArray :: !(Array U VShape Double)}

A HistogramRepa can be constructed from a Histogram,

systemsHistogramsHistogramRepa :: System -> Histogram -> Maybe HistogramRepa

systemsHistogramRepasHistogram :: System -> HistogramRepa -> Maybe Histogram

For example,

let aaar uu aa = fromJust $ systemsHistogramsHistogramRepa uu aa

let araa uu rr = fromJust $ systemsHistogramRepasHistogram uu rr

let aa = regdiag 2 2

rp $ aa
"{({(1,1),(2,1)},1 % 1),({(1,2),(2,2)},1 % 1)}"

aa
Histogram (fromList [(State (fromList [(VarInt 1,ValInt 1),(VarInt 2,ValInt 1)]),1 % 1),(State (fromList [(VarInt 1,ValInt 2),(VarInt 2,ValInt 2)]),1 % 1)])

let ar = aaar (sys aa) aa

ar
HistogramRepa {histogramRepasVectorVar = [VarInt 1,VarInt 2], histogramRepasMapVarInt = fromList [(VarInt 1,0),(VarInt 2,1)], histogramRepasArray = AUnboxed [2,2] [1.0,0.0,0.0,1.0]}

rp $ araa (sys aa) ar
"{({(1,1),(2,1)},1 % 1),({(1,1),(2,2)},0 % 1),({(1,2),(2,1)},0 % 1),({(1,2),(2,2)},1 % 1)}"

trim (araa (sys aa) ar) == aa
True

A HistogramRepa consists of (i) a bijective map between tuple position and variable, histogramRepasVectorVar, implemented as a vector, (ii) the lazy inverse of this map, histogramRepasMapVarInt, and (iii) the multi-dimensional unboxed array of Double, histogramRepasArray. For example

:t histogramRepasVectorVar ar
histogramRepasVectorVar ar :: V.Vector Variable

histogramRepasVectorVar ar
[VarInt 1,VarInt 2]

:t histogramRepasMapVarInt ar
histogramRepasMapVarInt ar :: Map.Map Variable Int

histogramRepasMapVarInt ar
fromList [(VarInt 1,0),(VarInt 2,1)]

:t histogramRepasArray ar
histogramRepasArray ar :: RB.Array R.U VShape Double

histogramRepasArray ar
AUnboxed [2,2] [1.0,0.0,0.0,1.0]

The VShape type is defined in module AlignmentRepaVShape as an unboxed vector of integers,

type VShape = Vector Int

VShape is an instance of typeclass Shape,

instance Shape VShape where
  ...
    toIndex !vv1 !vv2
  ...
    fromIndex !vv !n
  ...

VShape defines the multi-dimensional shape polymorphism in functions toIndex and fromIndex which convert to and from index integers given a tuple of valencies and a tuple of integal values. The shape of the histogram is obtained

R.extent $ histogramRepasArray ar
[2,2]

The array can be indexed

histogramRepasArray ar R.! UV.fromList [0,0]
1.0

histogramRepasArray ar R.! UV.fromList [0,1]
0.0 

Like Histogram, HistogramRepa can be reduced,

setVarsHistogramRepasReduce :: Set.Set Variable -> HistogramRepa -> HistogramRepa 

For example,

let arred aa vv = setVarsHistogramRepasReduce vv aa

ar `arred` Set.singleton (VarInt 2)
HistogramRepa {histogramRepasVectorVar = [VarInt 2], histogramRepasMapVarInt = fromList [(VarInt 2,0)], histogramRepasArray = AUnboxed [2] [1.0,1.0]}

ar `arred` Set.empty
HistogramRepa {histogramRepasVectorVar = [], histogramRepasMapVarInt = fromList [], histogramRepasArray = AUnboxed [] [2.0]}

The independent, $A^{\mathrm{X}}$, has an intermediate representation in terms of a vector of its normalised perimeters, $\{\hat{A}\%\{w\} : w \in V\}$. Module AlignmentRepa defines type HistogramRepaRed,

data HistogramRepaRed = HistogramRepaRed {
  histogramRepaRedsVectorVar :: !(V.Vector Variable),
  histogramRepaRedsMapVarInt :: Map.Map Variable Int,
  histogramRepaRedsShape :: !VShape,
  histogramRepaRedsVectorArray :: !(V.Vector (UV.Vector Double))}

Instead of an array, histogramRepasArray, the HistogramRepaRed has a vector of unboxed vectors of Double representing the normalised reductions to each of the variables, histogramRepaRedsVectorArray,

histogramRepasRed_u :: Double -> HistogramRepa -> HistogramRepaRed 

For example,

let arpr = histogramRepasRed_u

histogramRepaRedsVectorArray $ arpr 2 ar
[[0.5,0.5],[0.5,0.5]]

Given the HistogramRepaRed the independent may be calculated,

histogramRepaRedsIndependent :: Double -> HistogramRepaRed -> HistogramRepa 

For example,

let prind = histogramRepaRedsIndependent

araa (sys aa) (prind 2 (arpr 2 ar)) == ind aa
True

Often a histogram and its shuffle are processed together, so module AlignmentRepa also defines type HistogramRepaVec which implements a vector of congruent histograms each in array histogram representation. That is, the size and set of variables are the shared by all of the histograms,

data HistogramRepaVec = HistogramRepaVec {
  histogramRepaVecsVectorVar :: !(V.Vector Variable),
  histogramRepaVecsMapVarInt :: Map.Map Variable Int,
  histogramRepaVecsSize :: !Double,
  histogramRepaVecsShape :: !VShape,
  histogramRepaVecsArray :: !(V.Vector (UV.Vector Double))}

Similarly, module AlignmentRepa also defines a vector of perimeters, type HistogramRepaRedVec,

data HistogramRepaRedVec = HistogramRepaRedVec {
  histogramRepaRedVecsVectorVar :: !(V.Vector Variable),
  histogramRepaRedVecsMapVarInt :: Map.Map Variable Int,
  histogramRepaRedVecsSize :: !Double,
  histogramRepaRedVecsShape :: !VShape,
  histogramRepaRedVecsVectorArray :: !(V.Vector (V.Vector (UV.Vector Double)))}

History and HistoryRepa

Histories are defined in the overview in section ‘States, histories and histograms’ P8 and in the paper in section ‘Histories’ P92. The discussion of the Haskell implementation of Histories is in the Haskell implementation of the Overview.

The set of histories is a subset of the state valued functions of event identifiers, $\mathcal{H} \subset \mathcal{X} \to \mathcal{S}$. The History type is defined in module Alignment with a Map.Map from Id to State,

newtype History = History (Map.Map Id State) 

This set-theoretic implementation is a poset binary map representation.

Section ‘Computation of histograms’ P406 of the paper discusses the list representation of histograms. Here the histogram, $A \in \mathcal{S} \to \mathbf{Q}_{\geq 0}$, is represented as a vector of pairs of the state and count, $\mathcal{L}(\mathbf{N}^n \times \mathbf{Q}_{\geq 0})$, where a state $S \in A^{\mathrm{S}}$ is represented in terms of a vector of length $n$ consisting of integral values, $\{u : (w,u) \in S\}^n \subset \mathcal{L}(\mathbf{N})$.

Similarly, a history $H \in \mathcal{H}$ can be represented as a list of the states, $\mathrm{ran}(H) \subset \mathcal{S}$, in a two dimensional array of integral values, $\mathbf{N}^{zn}$, of size $zn$, where $z = |H|$. The literal event identifiers, $\mathrm{dom}(H) \subset \mathcal{X}$, are dropped and are encoded instead by the order of the states in the vector.

The module AlignmentRepa defines type HistoryRepa in terms of the two-dimensional array,

data HistoryRepa = HistoryRepa {
  historyRepasVectorVar :: !(V.Vector Variable),
  historyRepasMapVarInt :: Map.Map Variable Int,
  historyRepasShape :: !VShape,
  historyRepasArray :: !(Array U DIM2 Int)}

A HistoryRepa can be constructed from a History,

systemsHistoriesHistoryRepa :: System -> History -> Maybe HistoryRepa

For example,

let hhhr uu hh = fromJust $ systemsHistoriesHistoryRepa uu hh

let hrhh uu hr = fromJust $ systemsHistoryRepasHistory_u uu hr

let aahr aa = hhhr (sys aa) $ aahh aa 

let aa = regdiag 2 2

rp $ aa
"{({(1,1),(2,1)},1 % 1),({(1,2),(2,2)},1 % 1)}"

let hr = aahr aa

hr
HistoryRepa {historyRepasVectorVar = [VarInt 1,VarInt 2], historyRepasMapVarInt = fromList [(VarInt 1,0),(VarInt 2,1)], historyRepasShape = [2,2], historyRepasArray = AUnboxed ((Z :. 2) :. 2) [0,1,0,1]}

A HistoryRepa consists of (i) a bijective map between tuple position and variable, historyRepasVectorVar, (ii) the lazy inverse of this map, historyRepasMapVarInt, (iii) the shape, historyRepasShape, and (iv) the two-dimensional unboxed array of Int, historyRepasArray. For example

historyRepasVectorVar hr
[VarInt 1,VarInt 2]

historyRepasMapVarInt hr
fromList [(VarInt 1,0),(VarInt 2,1)]

historyRepasShape hr
[2,2]

historyRepasArray hr
AUnboxed ((Z :. 2) :. 2) [0,1,0,1]

A HistoryRepa can also be constructed from lists of lists of integers,

systemsListVariablesListsListsHistoryRepa :: System -> [Variable] -> [[Int]] -> Maybe HistoryRepa

historyRepasListsList :: HistoryRepa -> [[Int]] 

For example,

let aa = regcart 3 2

rpln $ aall $ aa
"({(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)"

let hr = aahr aa

historyRepasVectorVar hr
[VarInt 1,VarInt 2]

historyRepasArray hr
AUnboxed ((Z :. 2) :. 9) [0,0,0,1,1,1,2,2,2,0,1,2,0,1,2,0,1,2]

historyRepasListsList hr
[[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[2,0],[2,1],[2,2]]

let uu = sys aa

let hr' = fromJust $ systemsListVariablesListsListsHistoryRepa uu [VarInt 1,VarInt 2] [[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[2,0],[2,1],[2,2]]

hr' == hr
True

rpln $ aall $ hhaa $ hrhh uu $ hr'
"({(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)"

Given a list of event identifier positions, a subset of events or a slice of a HistoryRepa may be selected,

eventsHistoryRepasHistoryRepaSelection :: [Int] -> HistoryRepa -> HistoryRepa 

For example,

rpln $ aall $ hhaa $ hrhh uu $ eventsHistoryRepasHistoryRepaSelection [0] hr
"({(1,1),(2,1)},1 % 1)"

rpln $ aall $ hhaa $ hrhh uu $ eventsHistoryRepasHistoryRepaSelection [0,4,8] hr
"({(1,1),(2,1)},1 % 1)"
"({(1,2),(2,2)},1 % 1)"
"({(1,3),(2,3)},1 % 1)"

rpln $ aall $ hhaa $ hrhh uu $ eventsHistoryRepasHistoryRepaSelection [0..8] hr
"({(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)"

A HistoryRepa can be reduced to another HistoryRepa,

setVarsHistoryRepasHistoryRepaReduced :: Set.Set Variable -> HistoryRepa -> HistoryRepa 

For example,

let hrredhr hh vv = setVarsHistoryRepasHistoryRepaReduced (Set.fromList vv) hh

rpln $ aall $ hhaa $ hrhh uu $ hr `hrredhr` [VarInt 1, VarInt 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)"

rpln $ aall $ hhaa $ hrhh uu $ hr `hrredhr` [VarInt 1]
"({(1,1)},3 % 1)"
"({(1,2)},3 % 1)"
"({(1,3)},3 % 1)"

rpln $ aall $ hhaa $ hrhh uu $ hr `hrredhr` [VarInt 2]
"({(2,1)},3 % 1)"
"({(2,2)},3 % 1)"
"({(2,3)},3 % 1)"

rpln $ aall $ hhaa $ hrhh uu $ hr `hrredhr` []
"({},9 % 1)"

A HistoryRepa can be reduced to a HistogramRepa,

setVarsHistoryRepasReduce :: Double -> Set.Set Variable -> HistoryRepa -> HistogramRepa 

For example,

let hrred hh vv = setVarsHistoryRepasReduce 1 (Set.fromList vv) hh

rpln $ aall $ araa uu $ hr `hrred` [VarInt 1, VarInt 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)"

rpln $ aall $ araa uu $ hr `hrred` [VarInt 1]
"({(1,1)},3 % 1)"
"({(1,2)},3 % 1)"
"({(1,3)},3 % 1)"

rpln $ aall $ araa uu $ hr `hrred` [VarInt 2]
"({(2,1)},3 % 1)"
"({(2,2)},3 % 1)"
"({(2,3)},3 % 1)"

rpln $ aall $ araa uu $ hr `hrred` []
"({},9 % 1)"

The vector of its normalised perimeters may be obtained from the HistoryRepa,

historyRepasRed :: HistoryRepa -> HistogramRepaRed 

For example,

let hrhx = historyRepasRed

histogramRepaRedsVectorArray $ hrhx $ hr
[[0.3333333333333333,0.3333333333333333,0.3333333333333333],[0.3333333333333333,0.3333333333333333,0.3333333333333333]]

histogramRepaRedsVectorArray $ hrhx $ hr `hrredhr` [VarInt 1]
[[0.3333333333333333,0.3333333333333333,0.3333333333333333]]

histogramRepaRedsVectorArray $ hrhx $ hr `hrredhr` []
[]

The vector of its normalised perimeters may be obtained from the HistoryRepa for a subset of the variables,

setVarsHistoryRepasRed :: Set.Set Variable -> HistoryRepa -> HistogramRepaRed 

For example,

let hrredhx hh vv = setVarsHistoryRepasRed (Set.fromList vv) hh

histogramRepaRedsVectorArray $ hr `hrredhx` [VarInt 1, VarInt 2]
[[0.3333333333333333,0.3333333333333333,0.3333333333333333],[0.3333333333333333,0.3333333333333333,0.3333333333333333]]

histogramRepaRedsVectorArray $ hr `hrredhx` [VarInt 1]
[[0.3333333333333333,0.3333333333333333,0.3333333333333333]]

histogramRepaRedsVectorArray $ hr `hrredhx` []
[]

Transform and TransformRepa

Transforms are defined in the overview in section ‘Transforms’ P35 and in the paper in section ‘Transforms’ P111. The discussion of the Haskell implementation of Transforms is in the Haskell implementation of the Overview.

The set of all transforms is $\mathcal{T} := \{(X,W) : X \in \mathcal{A},~W \subseteq \mathrm{vars}(X)\}$. Given a histogram $X \in \mathcal{A}$ and a subset of its variables $W \subseteq \mathrm{vars}(X)$, the pair $T = (X,W)$ forms a transform. The Transform type is defined in module Alignment with a pair of a Histogram and a Variable set,

newtype Transform = Transform (Histogram, (Set.Set Variable))

The implementation of the Histogram is a poset binary map representation.

Given a histogram $A \in \mathcal{A}$, the multiplication of the histogram, $A$, by the transform $T \in \mathcal{T}$ equals the multiplication of the histogram, $A$, by the transform histogram $X = \mathrm{his}(T)$ followed by the reduction to the derived variables $W = \mathrm{der}(T)$, $A * T := A * X~\%~W$. Section ‘Computation of histograms’ P407 discusses the reduction and multiplication of histograms. Then the discussion goes on (P408) to consider the multiplication to two histograms $A * B$ where the second histogram, $B$, is the histogram of some one functional transform $T \in \mathcal{T}_{U,\mathrm{f},1}$. This multiplication can be thought of as adding variables to $A$ without changing the cardinality or the counts. The computation of the application need only remap the states without modifying the counts however they are represented. No multiplications nor additions are computed. See section ‘Computation of the application of a transform’ P409.

Consider the case where the one functional transform, $T$, has a single derived variable $\{w\} = \mathrm{der}(T)$. The histogram, $X$, may then be represented as an array of the derived values, $U_w^v$, of size equal to the underlying volume, $v$. The module AlignmentRepa defines type TransformRepa in terms of a multi-dimensional array of the integral values of the derived variable,

data TransformRepa = TransformRepa {
  transformRepasVectorVar :: !(V.Vector Variable),
  transformRepasMapVarInt :: Map.Map Variable Int,
  transformRepasVarDerived :: !Variable,
  transformRepasValency :: !Int,
  transformRepasArray :: !(Array U VShape Int)}

A TransformRepa can be constructed from a Transform,

systemsTransformsTransformRepa :: System -> Transform -> Maybe TransformRepa

For example,

let cdtt pp ll = trans (cdaa ll `cdtp` pp) (Set.singleton (VarInt (last pp)))

let tt = cdtt [1,2,3] [[1,1,1],[1,2,1],[1,3,1],[2,1,2],[2,2,2],[2,3,2],[3,1,2],[3,2,2],[3,3,1]]

rpln $ aall $ ttaa tt
"({(1,1),(2,1),(3,1)},1 % 1)"
"({(1,1),(2,2),(3,1)},1 % 1)"
"({(1,1),(2,3),(3,1)},1 % 1)"
"({(1,2),(2,1),(3,2)},1 % 1)"
"({(1,2),(2,2),(3,2)},1 % 1)"
"({(1,2),(2,3),(3,2)},1 % 1)"
"({(1,3),(2,1),(3,2)},1 % 1)"
"({(1,3),(2,2),(3,2)},1 % 1)"
"({(1,3),(2,3),(3,1)},1 % 1)"

let tttr tt = fromJust $ systemsTransformsTransformRepa (sys (ttaa tt)) tt

let tr = tttr tt

tr
TransformRepa {transformRepasVectorVar = [VarInt 1,VarInt 2], transformRepasMapVarInt = fromList [(VarInt 1,0),(VarInt 2,1)], transformRepasVarDerived = VarInt 3, transformRepasValency = 2, transformRepasArray = AUnboxed [3,3] [0,0,0,1,1,1,1,1,0]}

A TransformRepa consists of (i) a bijective map between tuple position and variable, transformRepasVectorVar, (ii) the lazy inverse of this map, transformRepasMapVarInt, (iii) the derived variable, transformRepasVarDerived, (iv) the derived valency, transformRepasValency and (v) the multi-dimensional unboxed array of Int, transformRepasArray. For example

transformRepasVectorVar tr
[VarInt 1,VarInt 2]

transformRepasMapVarInt tr
fromList [(VarInt 1,0),(VarInt 2,1)]

transformRepasVarDerived tr
VarInt 3

transformRepasValency tr
2

transformRepasArray tr
AUnboxed [3,3] [0,0,0,1,1,1,1,1,0]

A TransformRepa may be applied to a HistoryRepa to generate a HistoryRepa reduced to the derived variable,

historyRepasTransformRepasApply_u :: HistoryRepa -> TransformRepa -> HistoryRepa 

For example,

let aa = regcart 3 2

rpln $ aall $ aa
"({(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)"

let hr = aahr aa

let trmul = historyRepasTransformRepasApply_u

rpln $ aall $ hhaa $ hrhh (sysreg 3 3) $ hr `trmul` tr
"({(3,1)},4 % 1)"
"({(3,2)},5 % 1)"

let aa = regdiag 3 2

rpln $ aall $ aa
"({(1,1),(2,1)},1 % 1)"
"({(1,2),(2,2)},1 % 1)"
"({(1,3),(2,3)},1 % 1)"

let hr = aahr aa

rpln $ aall $ hhaa $ hrhh (sysreg 3 3) $ hr `trmul` tr
"({(3,1)},2 % 1)"
"({(3,2)},1 % 1)"

Section ‘Computation of functional definition sets’ P408 discusses the application of a one functional definition set $F \in \mathcal{F}_{U,1}$ of one functional transforms to a histogram, $A * F$. The sequence of the application of the transforms can be ordered by layer so that the cardinality of the intermediate histogram remains that of the given histogram, $|A|$.

A vector of TransformRepa can be ordered by layer,

listVariablesListTransformRepasSort :: V.Vector Variable -> V.Vector TransformRepa -> V.Vector TransformRepa 

This sort followed by the application in sequence allows the application of a fud consisting of an arbitrary vector of TransformRepa to a HistoryRepa. Note that the application is really a multiply because the resultant HistoryRepa is not reduced to the fud derived variables,

historyRepasListTransformRepasApply :: HistoryRepa -> V.Vector TransformRepa -> HistoryRepa 

For example,

let tt1 = cdtt [1,3] [[1,1],[2,1],[3,2]]

let tt2 = cdtt [1,4] [[1,1],[2,2],[3,2]]

let tt3 = cdtt [3,4,5] [[1,1,1],[1,2,1],[2,1,1],[2,2,2]]

let ltrmul hr ll = historyRepasListTransformRepasApply hr (V.fromList ll)

rpln $ aall $ hhaa $ hrhh (sysreg 3 5) $ hr `ltrmul` [tttr tt3,tttr tt1,tttr tt2]
"({(1,1),(2,1),(3,1),(4,1),(5,1)},1 % 1)"
"({(1,2),(2,2),(3,1),(4,2),(5,1)},1 % 1)"
"({(1,3),(2,3),(3,2),(4,2),(5,2)},1 % 1)"

Given a fud, the construction of the vector of TransformRepa and its application to a HistoryRepa is wrapped up as

systemsFudsHistoryRepasMultiply :: System -> Fud -> HistoryRepa -> Maybe HistoryRepa 

For example,

let frmul hr ff = fromJust $ systemsFudsHistoryRepasMultiply (fsys ff) ff hr

let ff = llff [tt3,tt1,tt2]

rpln $ aall $ hhaa $ hrhh (sysreg 3 5) $ hr `frmul` ff
"({(1,1),(2,1),(3,1),(4,1),(5,1)},1 % 1)"
"({(1,2),(2,2),(3,1),(4,2),(5,1)},1 % 1)"
"({(1,3),(2,3),(3,2),(4,2),(5,2)},1 % 1)"

Similarly, given a fud decomposition the application to a HistoryRepa results in a tree of HistoryRepa reduced to node fud derived variables,

systemsDecompFudsHistoryRepasMultiply :: System -> DecompFud -> HistoryRepa -> Tree ((State,Fud),HistoryRepa)

top