Matrix transpose again! :)
Author Message
Matrix transpose again! :)

to accomplish this task. Here is my proposal (see my question from the
end of this post):
------------------------------
domains
i = integer
pi = i*
ppi = pi*

predicates
trans(ppi, ppi)
trans_row(pi, ppi, ppi)

clauses

trans([], []).

trans([A1x1_n|A2_nx1_n], B):-
trans(A2_nx1_n, BB),
trans_row(A1x1_n, BB, B).

trans_row([], _, []).

trans_row([A1|A2_n], [], [[A1]|B2_nx1_n]):-
trans_row(A2_n, [], B2_nx1_n).

trans_row([A1|A2_n], [BB1x1_n|BB2_nx1_n], [[A1|BB1x1_n]|B2_nx1_n]):-
trans_row(A2_n, BB2_nx1_n, B2_nx1_n).
------------------------------
It works properly with goals like:
trans([[1,2,3],[4,5,6]], B)
B=[[1,4],[2,5],[3,6]]
1 Solution

trans([[1,2,3],[4,5,6]], [[1,4],[2,5],[3,6]])
True

trans([[1,2,3],[4,5,6],[7,8],[9,10]], B)
B=[[1,4,7,9],[2,5,8,10],[3,6]]
1 Solution

But if I try goal:
trans(A, [[1,4],[2,5],[3,6]])

I get: "3008  WARNING: The variable is not bound in this clause.
(F10=ok, Esc=abort)"
and it's not working properly - results are not deterministic (I've had
to kill the task, because it prodeces so many results!).

Any ideas how to make it deterministic, and remove warning?
--
-- http://www.*-*-*.com/ ------
-- AGH - EAIiE - robotics -----

Sat, 31 May 2003 20:27:22 GMT
Matrix transpose again! :)

Quote:
way
> to accomplish this task. Here is my proposal (see my question from
the
> end of this post):
> ------------------------------
> domains
> i = integer
> pi = i*
> ppi = pi*

> predicates
> trans(ppi, ppi)
> trans_row(pi, ppi, ppi)

> clauses

> trans([], []).

> trans([A1x1_n|A2_nx1_n], B):-
> trans(A2_nx1_n, BB),
> trans_row(A1x1_n, BB, B).

> trans_row([], _, []).

> trans_row([A1|A2_n], [], [[A1]|B2_nx1_n]):-
> trans_row(A2_n, [], B2_nx1_n).

> trans_row([A1|A2_n], [BB1x1_n|BB2_nx1_n], [[A1|BB1x1_n]|B2_nx1_n]):-
> trans_row(A2_n, BB2_nx1_n, B2_nx1_n).
> ------------------------------
> It works properly with goals like:
> trans([[1,2,3],[4,5,6]], B)
> B=[[1,4],[2,5],[3,6]]
> 1 Solution

> trans([[1,2,3],[4,5,6]], [[1,4],[2,5],[3,6]])
> True

> trans([[1,2,3],[4,5,6],[7,8],[9,10]], B)
> B=[[1,4,7,9],[2,5,8,10],[3,6]]
> 1 Solution

> But if I try goal:
> trans(A, [[1,4],[2,5],[3,6]])

> I get: "3008  WARNING: The variable is not bound in this clause.
> (F10=ok, Esc=abort)"
> and it's not working properly - results are not deterministic (I've
> to kill the task, because it prodeces so many results!).

> Any ideas how to make it deterministic, and remove warning?

If you're looking for predicate reversibility, then this
seems to do the trick:

trans([], []):-
!.
trans(A, [B1x1_n|B2_nx1_n]):-  % LEFT-TRANSFORM
free(A),
bound(B1x1_n),
bound(B2_nx1_n),
!,
trans(AA, B2_nx1_n),
trans_row(B1x1_n, AA, A).
trans([A1x1_n|A2_nx1_n], B):-  % RIGHT-TRANSFORM OR TEST
trans(A2_nx1_n, BB),
trans_row(A1x1_n, BB, B).

Note that this isn't tested beyond your example goals.

Daniel

Sun, 01 Jun 2003 03:54:21 GMT
Matrix transpose again! :)
[]

Quote:
> If you're looking for predicate reversibility, then this
> seems to do the trick:

[]

> Note that this isn't tested beyond your example goals.

Thanks! It's working almost perfectly (except one type of goal).
Nothing has changed with goals like:
trans([[1,2,3],[4,5,6]], B)
trans([[1,2,3],[4,5,6],[7,8],[9,10]], B)

Now it's working with revers order:
trans(A, [[1,2,3],[4,5,6]])
trans(A, [[1,4],[2,5],[3,6]])

BUT (!) there is a warning with goal for testing, for example:
trans([[1,2,3],[4,5,6]], [[1,4],[2,5],[3,6]])

(first variable A1 in predicate trans_row is unbound)
-------------
trans_row([A1|A2_n], [], [[A1]|B2_nx1_n]):-
trans_row(A2_n, [], B2_nx1_n).

3008  WARNING: The variable is not bound in this cla
use. (F10=ok, Esc=abort)
--------------

--
-- http://www.kaspy.z.pl ------
-- AGH - EAIiE - robotics -----

Sun, 01 Jun 2003 06:29:23 GMT
Matrix transpose again! :)
[]

Quote:
> If you're looking for predicate reversibility, then this
> seems to do the trick:

[]

> Note that this isn't tested beyond your example goals.

Thanks! It's working almost perfectly (except one type of goal).
Nothing has changed with goals like:
trans([[1,2,3],[4,5,6]], B)
trans([[1,2,3],[4,5,6],[7,8],[9,10]], B)

Now it's working with revers order:
trans(A, [[1,2,3],[4,5,6]])
trans(A, [[1,4],[2,5],[3,6]])

BUT (!) there is a warning with goal for testing, for example:
trans([[1,2,3],[4,5,6]], [[1,4],[2,5],[3,6]])

(first variable A1 in predicate trans_row is unbound)
-------------
trans_row([A1|A2_n], [], [[A1]|B2_nx1_n]):-
trans_row(A2_n, [], B2_nx1_n).

3008  WARNING: The variable is not bound in this cla
use. (F10=ok, Esc=abort)
--------------

--
-- http://www.kaspy.z.pl ------
-- AGH - EAIiE - robotics -----

Sun, 01 Jun 2003 06:29:41 GMT
Matrix transpose again! :)

Quote:

> []
> > If you're looking for predicate reversibility, then this
> > seems to do the trick:

> []

> > Note that this isn't tested beyond your example goals.

> Thanks! It's working almost perfectly (except one type of goal).
> Nothing has changed with goals like:
> trans([[1,2,3],[4,5,6]], B)
> trans([[1,2,3],[4,5,6],[7,8],[9,10]], B)

> Now it's working with revers order:
> trans(A, [[1,2,3],[4,5,6]])
> trans(A, [[1,4],[2,5],[3,6]])

> BUT (!) there is a warning with goal for testing, for example:
> trans([[1,2,3],[4,5,6]], [[1,4],[2,5],[3,6]])

> (first variable A1 in predicate trans_row is unbound)
> -------------
> trans_row([A1|A2_n], [], [[A1]|B2_nx1_n]):-
>         trans_row(A2_n, [], B2_nx1_n).

> 3008  WARNING: The variable is not bound in this cla
> use. (F10=ok, Esc=abort)
> --------------

Works fine for me using both VIP 5.1 and 5.2.
No error or warning messages either.

If you have replaced your trans/2 code with my version then
all should be well. The only other suggestion I can offer
you is that you check your VIP settings.

Daniel

Sun, 01 Jun 2003 07:40:02 GMT
Matrix transpose again! :)
[]

Quote:

> Works fine for me using both VIP 5.1 and 5.2.
> No error or warning messages either.

> If you have replaced your trans/2 code with my version then
> all should be well. The only other suggestion I can offer
> you is that you check your VIP settings.

I've Turbo Prolog 1.1 . This works fine, except only one warning when I
try goal to check two given matrices, like: trans([[1,2,3],[4,5,6]],
[[1,4],[2,5],[3,6]])).
My code with yours trans/1 and trans/2 is:

trans([], []):-
!.

trans(A, [B1x1_n|B2_nx1_n]):-
free(A),
bound(B1x1_n),
bound(B2_nx1_n),
!,
trans(AA, B2_nx1_n),
trans_row(B1x1_n, AA, A).

trans([A1x1_n|A2_nx1_n], B):-
trans(A2_nx1_n, BB),
trans_row(A1x1_n, BB, B).

trans_row([], _, []).

trans_row([A1|A2_n], [], [[A1]|B2_nx1_n]):-
trans_row(A2_n, [], B2_nx1_n).

trans_row([A1|A2_n], [BB1x1_n|BB2_nx1_n], [[A1|BB1x1_n]|B2_nx1_n]):-
trans_row(A2_n, BB2_nx1_n, B2_nx1_n).

--
-- http://www.kaspy.z.pl ------
-- AGH - EAIiE - robotics -----

Sun, 01 Jun 2003 08:39:31 GMT
Matrix transpose again! :)

Quote:

> []

> > Works fine for me using both VIP 5.1 and 5.2.
> > No error or warning messages either.

I think it's something wrong with my compiler, because I've found both
goal, like:
trans(A, [[1,2,3],[4,5,6]])
or:
trans([[1,2,3],[4,5,6]], [[1,4],[2,5],[3,6]])

generates warning with predicate trans_row/2
The warning appears only once (!) with first given goal, with next goal,
it's not displayed! Strange.

--
-- http://www.kaspy.z.pl ------
-- AGH - EAIiE - robotics -----

Sun, 01 Jun 2003 08:54:16 GMT
Matrix transpose again! :)

Quote:

> []

> > Works fine for me using both VIP 5.1 and 5.2.
> > No error or warning messages either.

> > If you have replaced your trans/2 code with my version
> > then all should be well. The only other suggestion I
> > can offer you is that you check your VIP settings.

> I've Turbo Prolog 1.1 . This works fine, except only one
> warning when I try goal to check two given matrices,
> like: trans([[1,2,3],[4,5,6]],[[1,4],[2,5],[3,6]])).
> My code with yours trans/1 and trans/2 is:

> trans([], []):-
> !.

> trans(A, [B1x1_n|B2_nx1_n]):-
> free(A),
> bound(B1x1_n),
> bound(B2_nx1_n),
> !,
> trans(AA, B2_nx1_n),
> trans_row(B1x1_n, AA, A).

> trans([A1x1_n|A2_nx1_n], B):-
> trans(A2_nx1_n, BB),
> trans_row(A1x1_n, BB, B).

> trans_row([], _, []).

> trans_row([A1|A2_n], [], [[A1]|B2_nx1_n]):-
> trans_row(A2_n, [], B2_nx1_n).

> trans_row([A1|A2_n], [BB1x1_n|BB2_nx1_n], [[A1|BB1x1_n]|B2_nx1_n]):-
> trans_row(A2_n, BB2_nx1_n, B2_nx1_n).

Well, you could try changing trans_row/3 to:

trans_row([], _, []):-
!.
trans_row([A1|A2_n], [], [[A1]|B2_nx1_n]):-
!,
trans_row(A2_n, [], B2_nx1_n).
trans_row([A1|A2_n],
[BB1x1_n|BB2_nx1_n],
[[A1|BB1x1_n]|B2_nx1_n]
):-
trans_row(A2_n, BB2_nx1_n, B2_nx1_n).

The example goals work fine here too - using VIP.

If this doesn't work, I can only suggest you update to VIP,
which has many improvements over the antiquated Turbo
Prolog :-(

Daniel

Mon, 02 Jun 2003 04:34:27 GMT
Matrix transpose again! :)
[]

Quote:

> Well, you could try changing trans_row/3 to:

[]

It didn't help. It seems there is a problem with my compiler. I've found
predicates "free" and "bound" very useful. I think trans/2 could be
simpler:

trans(A, B):-
free(A),
trans(B, A),
!.

It works with all example goals (except the same warning appears with
trans_row/2).

Quote:
> The example goals work fine here too - using VIP.

Does VIP allow to try different goals after compilation?

Quote:

> If this doesn't work, I can only suggest you update to VIP,
> which has many improvements over the antiquated Turbo
> Prolog :-(

We use Turbo Prolog 1.1 during our course "Programming languages of AI".
TP it's simplest, and takes only about 300 kb with all examples.

--
-- http://www.kaspy.z.pl ------
-- AGH - EAIiE - robotics -----

Mon, 02 Jun 2003 08:37:43 GMT
Matrix transpose again! :)

Quote:

> []

> > Well, you could try changing trans_row/3 to:

> []

> It didn't help. It seems there is a problem with my compiler.
> I've found predicates "free" and "bound" very useful. I think
> trans/2 could be simpler:

> trans(A, B):-
> free(A),
> trans(B, A),
> !.

And if B is a free variable too? What if it is, in reality, a
compound variable partially instantiated when called
(recursively or directly by a user-goal)?

There's one benefit to your simplification, you'll get to
know the error messages very well. ;-)

Quote:
> It works with all example goals (except the same warning
> appears with trans_row/2).

> > The example goals work fine here too - using VIP.

> Does VIP allow to try different goals after compilation?

Yes, VIP has an interactive goal feature. In this respect, you
won't experience much difference from Turbo Prolog.

Quote:
> > If this doesn't work, I can only suggest you update to VIP,
> > which has many improvements over the antiquated Turbo
> > Prolog :-(

> We use Turbo Prolog 1.1 during our course "Programming
> languages of AI". TP it's simplest, and takes only about 300
> kb with all examples.

PDC Prolog, the successor to Turbo Prolog, is quite economical
on storage space; you may well find that suitable for your
needs. If you must work with a text-based UI (VIP has a GUI),
perhaps PDC http://www.pdc.dk/ would be willing to supply you
with a copy.

BTW, have you read the FAQ?

Daniel

Tue, 03 Jun 2003 02:19:41 GMT
Matrix transpose again! :)
[]

Quote:
> And if B is a free variable too? What if it is, in reality, a
> compound variable partially instantiated when called
> (recursively or directly by a user-goal)?

> There's one benefit to your simplification, you'll get to
> know the error messages very well. ;-)

There are no problems with any goal I tested.

Quote:
> BTW, have you read the FAQ?

No, I don't. Where I could find it?

--
-- http://www.kaspy.z.pl ------
-- AGH - EAIiE - robotics -----

Tue, 03 Jun 2003 09:25:48 GMT
Matrix transpose again! :)

Quote:

[snipped]
> > BTW, have you read the FAQ?

> No, I don't. Where I could find it?

It's the message with the subject "comp.lang.prolog

Daniel

Tue, 03 Jun 2003 23:59:12 GMT
Matrix transpose again! :)
[]

Quote:

> It's the message with the subject "comp.lang.prolog

> Daniel

I can't find such message.

--
-- http://www.kaspy.z.pl ------
-- AGH - EAIiE - robotics -----

Wed, 04 Jun 2003 03:03:01 GMT
Matrix transpose again! :)

Quote:

> > I've read previous post about matrix transpose. I've found another
> way
> > to accomplish this task. Here is my proposal (see my question from
> the
> > end of this post):
> > ------------------------------
> > domains
> > i = integer
> > pi = i*
> > ppi = pi*

> > predicates
> > trans(ppi, ppi)
> > trans_row(pi, ppi, ppi)

> > clauses

> > trans([], []).

> > trans([A1x1_n|A2_nx1_n], B):-
> > trans(A2_nx1_n, BB),
> > trans_row(A1x1_n, BB, B).

> > trans_row([], _, []).

> > trans_row([A1|A2_n], [], [[A1]|B2_nx1_n]):-
> > trans_row(A2_n, [], B2_nx1_n).

> > trans_row([A1|A2_n], [BB1x1_n|BB2_nx1_n], [[A1|BB1x1_n]|B2_nx1_n]):-
> > trans_row(A2_n, BB2_nx1_n, B2_nx1_n).
> > ------------------------------
> > It works properly with goals like:
> > trans([[1,2,3],[4,5,6]], B)
> > B=[[1,4],[2,5],[3,6]]
> > 1 Solution

> > trans([[1,2,3],[4,5,6]], [[1,4],[2,5],[3,6]])
> > True

> > trans([[1,2,3],[4,5,6],[7,8],[9,10]], B)
> > B=[[1,4,7,9],[2,5,8,10],[3,6]]
> > 1 Solution

> > But if I try goal:
> > trans(A, [[1,4],[2,5],[3,6]])

> > I get: "3008  WARNING: The variable is not bound in this clause.
> > (F10=ok, Esc=abort)"
> > and it's not working properly - results are not deterministic (I've
> > to kill the task, because it prodeces so many results!).

> > Any ideas how to make it deterministic, and remove warning?

> If you're looking for predicate reversibility, then this
> seems to do the trick:

>     trans([], []):-
>         !.
>     trans(A, [B1x1_n|B2_nx1_n]):-  % LEFT-TRANSFORM
>         free(A),
>         bound(B1x1_n),
>         bound(B2_nx1_n),
>         !,
>         trans(AA, B2_nx1_n),
>         trans_row(B1x1_n, AA, A).
>     trans([A1x1_n|A2_nx1_n], B):-  % RIGHT-TRANSFORM OR TEST
>         trans(A2_nx1_n, BB),
>         trans_row(A1x1_n, BB, B).

> Note that this isn't tested beyond your example goals.

> Daniel

no free , bound or ! (almost) cluttering the code

it seems to be reversible
and deterministic
(to be precise :
nondeterministic only with [] as argument ,
otherwise deterministic
)

(se **** below if you aren't interested in the rest)

i am hacking/testing/(developing) it in SICStus Prolog (3.8.5)
so maybe it's not possible to translate it to other prolog dialects ?

it uses higher-order-predicates map1,map3
(i think some of these is already available is SICStus libraries
i included ~= haskell function (which i have taken inspiration from)
callWith        apply                                   (\$)
map1            forall_list (or smthng like that)       all
map2            map_list (?)                            map
map3                                                    zipWith
)

below is (part) of file commonlib.pl :

----

:- module(commonlib,
[cons/3
,append/3
,concat/2
,transpose/2
,map1/2
,map2/3
,map3/4
,mapMulti/2
,foldl/4
,foldr/4
,callWith/2
]).

% cons( ?Head ,?Tail ,?NonEmptyList )
cons( X ,Xs ,[X|Xs] ).

% append( +BaseList ,+ExtensionList ,-ExtendedList ) det
% append( ?BaseList ,?ExtensionList ,+ExtendedList ) nondet
append( [     ] ,Xs ,    Xs  ).
append( [X|Xs0] ,Xs1 ,[X|Xs] ):-
append( Xs0 ,Xs1 ,Xs ).

%this is not reversible (due to foldr,i think)
%maybe one can make it semireversible in some way

% concat( ListOfLists ,ConcatenatedList )
concat( Xss , Xs ):-
foldr( append ,[] ,Xss ,Xs ).

%****
%hmm : i think this is reversible
%the only nondet case is with []

%maybe one can improve efficency of this (and preserve some
%high-orderness) (e.g with ackumulator perhaps ?? (or foldr))

% transpose( +ListOfLists ,?TransposedListOfLists )
% transpose( ?ListOfLists ,+TransposedListOfLists )
transpose( Xss0 ,[      ] ):-
map1( null ,Xss0 ).
transpose( Xss0 ,[Xs|Xss] ):-
map3( cons ,Xs ,Xss1 ,Xss0 ),
transpose( Xss1 ,Xss ).

%i seem to remember writing another different version of transpose,
%can't find it (or was it mapMulti ?)

%****

:- meta_predicate map1( : ,? ).

% map1( +Predicate ,?Xs )
map1( _ ,[    ] ).
map1( P ,[X|Xs] ):-
callWith( P , [X] ),
map1( P ,Xs ).

:- meta_predicate map2( : ,? ,? ).

% map2( +Predicate ,?Xs ,?Ys )
map2( _ ,[    ] ,[    ] ).
map2( P ,[X|Xs] ,[Y|Ys] ):-
callWith( P , [X,Y] ),
map2( P ,Xs ,Ys ).

:- meta_predicate map3( : ,? ,? ,? ).

% map3( +Predicate ,?Xs ,?Ys ,?Zs )
map3( _ ,[    ] ,[    ] ,[    ] ).
map3( P ,[X|Xs] ,[Y|Ys] ,[Z|Zs] ):-
callWith( P , [X,Y,Z] ),
map3( P ,Xs ,Ys ,Zs ).

:- meta_predicate mapMulti( : ,? ).

% mapMulti( Predicate ,ArgumentListOfLists )
mapMulti( P ,Xss0 ):-
transpose( Xss0, Xss ),
map1( callWith(P) ,Xss ).

:- meta_predicate callwith( : ,? ).

% callWith( :+OldPredicate ,+ExtraArgs )
callWith( P0 ,ExtraArgs ):-
P.

:- meta_predicate addPredArgs( : ,? ,: ).

%it seems that there is some problem when using addPredArgs with
%explicit module prefix when in top-level interpreter (but not in
%interpreted code !)

% addPredArgs( :+OldPredicate ,+ExtraArgs , :?NewPredicate )
!,

% addArgs( :+OldTerm ,+ExtraArgs , :?NewTerm )
T0 =.. [F|Args0],
append( Args0 ,ExtraArgs ,Args ),
T =.. [F|Args].

----

hmm ?

addPredArgs is for correct handling of module prefix