<< Prev | - Up - | Next >> |
We can now define products of domains. The elements of product domains are vectors (n-tuples) of elements of other domains. From the operational view, we have to provide converter functions that map vectors in to integer indexes and vice versa.
fun{Product Domains} %% list(domain) -> domain
DomTable = {List.toTuple unit Domains}
N = {Length Domains}
Size = {Prod 1 N fun{$ I}
DomTable.I.size
end}
%% forth conversion
<ToIndex>
%% back conversion
<ToVector>
in
unit(toIndex :ToIndex
toElement:ToVector
size :Size)
end
For simplicity, let us assume first that the elements of the given domains are already integer indexes:
We can then describe the index of a vector by the following formula.
This formula is well known for the case where all domains contain the digits , i.e. if
. In this case, the formula tells us how to read a sequence of digits as a decimal number (up to inversion).
For implementing the conversion from vectors to numbers, we use an Oz table DomTable
to index the domains by integers
. Note that we exploit the conversion functions of the factors of the product to define the conversion functions of the product itself.
fun{ToIndex Vector} %% list(feature) -> int
if {Length Vector} \= N
then raise unit(msg:'length of vector not valid'
function:'ToIndex'
file:'domain.oz'
vector:Vector
length:N)
end
end
VectorTable = {List.toTuple unit Vector}
in
{Sum 1 N fun{$ I}
{DomTable.I.toIndex VectorTable.I} *
{Prod 1 I-1 fun{$ J}
DomTable.J.size
end}
end}
end
The back translation from indexes to vectors of elements requires some division modulo operations, which require some care.
fun{ToVectorHelp Index N InVector}
if N==0
then InVector
else
Size={Prod 1 N-1 fun{$ I} DomTable.I.size end}
NextVector = {DomTable.N.toElement (Index div Size)} | InVector
in
{ToVectorHelp (Index mod Size) N-1 NextVector}
end
end
fun{ToVector Index} %% int -> list(feature)
if Index < 0 orelse Index > Size-1
then
raise error(function:'ToVector'
file:'domain.oz'
msg:'index out of range'
index:Index
range:0#(Size-1))
end
end
{ToVectorHelp Index N nil}
end
<< Prev | - Up - | Next >> |