1

I need to write a Prolog predicate to check:

  1. if all matrix elements on row are odd numbers program should add in the end of the row 1.
  2. if in the row are 1 or more even numbers program should add in the end of the row 0.
?- f([[1,2,3],[5,5,5],[4,4,4]], Xss).
Xss = [[1,2,3,0],[5,5,5,1],[4,4,4,0]].  

This is what I have now:

f([],[]).
f(matrix,Xss).
f([Xs|T],Xss):-
    Xs=[X|T2],
(X mod 2 =:= 0 ->
add2end(0,[X|T2],[X|Result]):-
add2end(0,T2, Result),
add2end(0,[],[0]), Xss=[Xs|T] ;
   add2end(1,[X|T2],[X|Result]):-
add2end(1,T2,Result),
    add2end(1,[],[1])), Xss=[Xs|T]..
repeat
  • 18,496
  • 4
  • 54
  • 166
user713744
  • 31
  • 1
  • 1
  • 5
  • I have problems with code writing... – user713744 Aug 19 '12 at 19:34
  • I have problems with code writing... a understand that I should have f([Matrix],[Result]). f([Matrix head| Matrix Tail],[Result]). Take a matrix head and from it take first element from the first list(row) of matrix [first element|another elements of 1 row] and check is it even number or not even(first element):- first element mod 2 = 0. if it is true, I should add 0 in the end of list add([first element|another elements of..], 0, [first element|new tail]):-add(another el,0,new tail). add([], first element, [first element]). But I don` t know how all this things write in code. – user713744 Aug 19 '12 at 19:47

2 Answers2

2

No problemo with and Prolog lambdas!

:- use_module(library(lambda)).
:- use_module(library(clpfd)).

We define f/2 based on maplist/3, sum/3, (#=)/2, and append/3:

f(Xss,Yss) :-
   maplist(\Xs^Ys^(sum(Xs,#=,S),P #= S mod 2,append(Xs,[P],Ys)), Xss, Yss).

Sample query:

?- f([[1,2,3],[5,5,5],[4,4,4]], Xss).
Xss = [[1,2,3,0], [5,5,5,1], [4,4,4,0]].    % succeeds deterministically   
Community
  • 1
  • 1
repeat
  • 18,496
  • 4
  • 54
  • 166
0

You can do something like this:

f([], []).
f([Row|Matrix], [NRow|NMatrix]):-
  f(Row, 1, NRow),
  f(Matrix, NMatrix).

f([], LastElem, [LastElem]).
f([Elem|Row], CurLastElem, [Elem|NRow]):-
  Elem mod 2 =:= 0 -> f(Row, 0, NRow) ; f(Row, CurLastElem, NRow).

Procedure f/2 will recurse over the Rows computing (and adding) the last element of each row. The first clause is the base case which ends recursion. The second clause will call a helper procedure f/3 in which the first argument will be the row to be computed, the second argument is the current value of the last element and the third argument will hold the result.

The first clause of the auxiliary procedure f/3 deals with the base case of each row. It will add the current LastElement to the row. The second clause tests the head of the row to see if it is even or odd. If it's even then the current LastElement is set to zero and recursion continues. If the element is odd then it continues recursion keeping the current LastElement as is.

This procedure can be optimized if you note that whenever you see an even element in a row then there really is no need to continue recursion of f/3 as you'd know that the last element will be 0... but that optimization is left as an exercise ;)

gusbro
  • 22,357
  • 35
  • 46