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

Reply via email to