I need help rewriting the following code as a functor
That can be invoked from the OPI, or invoked remotely.
Anyone willing to help?
declare
% Recursively flatten the list Ls one level, and return the result in
R.
proc {Concat Ls ?R}
case Ls of L|Lr then R1 in
R={Append L R1} R1={Concat Lr}
else R=nil end
end
% Exactly D elements of Dv have the value I. This is a rewrite of
% the built-in function FD.exactly, which has a bug in version 1.2.3.
% This is used to enforce the constraint that half the differences
% appear once and half appear twice, by counting differences that
% appear twice.
proc {Exactly D Dv TargetValue}
Ds = if {List.is Dv}
then Dv
else {Record.toList Dv} end
Bs = {Map Ds fun {$ E} E =: TargetValue end}
in
{FD.sum Bs '=:' D}
end
%%
%%
%%
fun {Autocorrelate Xs}
NumberOfShifts = {List.length Xs} - 1
in
for
I in 1..NumberOfShifts
collect:Collect
do
%% rotate the list Xs by: splitting the list at position I then
%% slicing the list back together with the parts swapped
CopyOfXsRotatedISlots={Append {List.drop Xs I} {List.take Xs I}}
Matches={List.zip Xs CopyOfXsRotatedISlots fun {$ X Y} X=:Y end}
Val
in
{FD.decl Val}
{FD.sum Matches '=:' Val}
{Collect Val}
end
end
%
% V is the size of the problem
%
fun {Design V}
if V mod 4 == 1
then
proc {$ Root}
Blocks
Diffs
Count
AutoCorrelationSequence
%I needed a variable to represent V-I to clean up code
%U is probably a bad choice when working with sets though.
U = V-1
%S is the size of the starter set S.
%S is usually calculated by dividing B (the number of blocks in the
design) by V.
S = U div 4
%T is (V-1) div 4, that is, V is congruent to 4*T + 1
T = S
N1 = U div 2
N2 = U - N1
Lambda1 = 1
Lambda2 = 2
%% BlockIds is a list of 23 integers in the interval 1..92
BlockIds = {FD.list S 1#(U*U)}
in
%% Blocks is a list of 23 "normalized" blocks
Blocks = {MakeList S}
Root = solution(design:Blocks v:V freqCount:Count
ac:AutoCorrelationSequence)
for B in Blocks Id in BlockIds do X Y in
[X Y] ::: 1#U
X =<: (V div 3)
2 * X =<: Y
Y <: V - X
B = [0 X Y]
Id =: X * V + Y
end
%% all blocks are pairwise distinct; we order them by Id in
order
%% to break more symmetries
for Id1 in BlockIds Id2 in BlockIds.2 do
Id1 <: Id2
end
%% Diffs is the list of all elements paired with 0
Diffs = {Concat {Map Blocks
fun {$ [0 X Y]}
L=[X Y {FD.minus Y X}]
in
{Append L {Map L fun {$ E}
{FD.minus V E} end}}
end}}
%% Count is a list of 92 integers in the interval 1..2
%% It is a histogram of the values in Diffs
Count = {FD.tuple histogram U 1#2}
for I in 1..U do
{Exactly Count.I Diffs I} % Count.I elements of Diffs
have the value I
Count.I =: Count.(V-I) % Count of Differences is
symmetrical, so we add this redundant constraint
end
{Exactly N2 Count Lambda2} % N2 number of elements appear
in Lambda2 blocks with 0 in the design
{Exactly N1 Count Lambda1} % N1 number of elements appear
in Lambda1 blocks with 0 in the design
% The autocorrelation sequence requires all V elements (by
definition)
% We don't have to calculate the value for 0, in this case, because 0
will never appear
% with 0 in any block. Therefore, we know the count for 0 is 0, and
we simply prefix it.
AutoCorrelationSequence = {Autocorrelate {Append [0]
{Record.toList Count}}}
for S in AutoCorrelationSequence
do
S=: (2*T - 1)
end %for
%% distributed on the variables in Blocks
{FD.distribute ff {Concat Blocks} }
end % {$ Blocks}
else proc {$ _} fail end
end %%case
end %%fun Design
%%
%% Call this when you want to use the Explorer GUI
%% It uses recomputation to save space.
%%
proc {ExploreGui V}
{Explorer.object option(search search:5 information:25 failed:true)}
{Explorer.object script({Design V})}
end
%%
%% Call this when you want to write results to a file
%%
proc {RunToFile V}
R
F
in
R = {Search.all {Design V} 20 _}
% Open a new file with a path to the desired location.
F={New Open.file
init(name: 'v_'#{Value.toVirtualString V 10 10}#'.txt'
flags: [write create]
mode: mode(owner: [read write]
group: [read write]))}
% For each list in the result set convert it to a tuple, then write
a newline character.
% The resulting file will give you one answer per line.
{ForAll R proc {$ X}
{F write(vs:{Value.toVirtualString X 1000
1000})}
{F write(vs:"\n")}
end
}
% Don't forget to close the file.
{F close}
end
%%{RunToFile 29}
{ExploreAll {Design 5}}
--------------------
George Rudolph
_________________________________________________________________________________
mozart-users mailing list
[email protected]
http://www.mozart-oz.org/mailman/listinfo/mozart-users