0

I want to create a multidimensional array in SICStus which woudld do pretty much the same thing as the ECLiPSe Dim function. For that I made this code, but unfortunetly it always enters in an infinite loop. Can anyone fix the problem?

    %multDimensional Array 2d
    mult(X,Y,Final):- mult(X,Y,0,Final).

    mult(X,_,X,[]).
    mult(X,Y,Count,[A|B]) :- length(List,Y),
              A = List,
              Count1 is Count+1,
              mult(X,Y,Count1,B).


    %multDimensional Array 3d
    mult2(Z,X,Y,Final):- mult2(X,Y,Z,0,Final),!.
    mult2(_,_,Z,Z,[]).
    mult2(X,Y,Z,Count,[A|B]):- multi(X,Y,0,Final),
                     Count1 is Count+1,
                     A = Final,
                     mult2(X,Y,Z,Count1,B).
    multi(X,_,X,[]).
    multi(X,Y,Count,[A|B]) :- length(List,Y),
              A = List,
              Count1 is Count+1,
              multi(X,Y,Count1,B).
false
  • 10,264
  • 13
  • 101
  • 209

2 Answers2

0

I guess you have to prevent the second clause of mult/4, multi/4 and mult2/5 to succeed when the first clause already succeeded (also note that mult/4 and multi/4 do the same)

For example, to fix mult/4 you can do something like this:

mult(X,_,X,[]).
mult(X,Y,Count,[A|B]) :-
  X\=Count,
  length(List,Y),
  A = List,
  Count1 is Count+1,
  mult(X,Y,Count1,B).

The same approach can be used to fix the other procedures

gusbro
  • 22,357
  • 35
  • 46
0

I can't replicate the problem with the infinite loop for queries like:

?- mult(3,4,F).
?- mult2(2,3,4,F).

However, ECLiPSe's dim/3 constructs a term of terms, not a list of lists. This should do the trick:

dim(Matrix, [Dim]) :-
    !,
    functor(Matrix, [], Dim).
dim(Matrix, [Dim|Rest]) :-
    functor(Matrix, [], Dim),
    Matrix =.. [_|Args],
    dim0(Args, Rest).

dim0([], _) :- !.
dim0([Arg|Rest], Dims) :-
    dim(Arg, Dims),
    dim0(Rest, Dims).

?- dim(Matrix, [2, 2, 2]).
Matrix = []([]([](_655, _656), [](_659, _660)), []([](_674, _675), [](_678, _679)))
Yes (0.00s cpu)
twinterer
  • 2,416
  • 1
  • 15
  • 13
  • SICStus has `current_prolog_flag(max_arity,255)` whereas ECLiPSe, like SWI, YAP is unbounded, B has 65535. – false Dec 06 '11 at 13:44
  • Thanks for pointing this out. This severely restricts the usefulness of arrays in SICStus. – twinterer Dec 06 '11 at 13:59