prolog pascal triangle - prolog

hi is there anybody know how can i do the pascal nth row
when i ask for
:? pascal(2,Row).
i get Row=[1,2,1]
??
please help me

Here is the code to compute the nth row.
The first part scans a row, to compute the next row. The first row must be prefixed with a 0, so that the first "1" in the next row is a sum, like the other elements. It recurses on the 2 lists:
pascal_next_row([X],[X]).
pascal_next_row([H,H2|T],[A|B]):-
pascal_next_row([H2|T],B),
A is H + H2.
The second part computes all the rows until the one which was asked. It recurses on N:
pascal(0, [1]) :- !.
pascal(N, R) :-
N1 is N-1,
pascal(N1, R1),
pascal_next_row([0|R1], R).
If you need the full triangle, all you have to do is change the second parameter to handle a list of rows, and collect them:
pascal(0, [[1]]) :- !.
pascal(N, [R, R1 | RN]) :-
N1 is N-1,
pascal(N1, [R1 | RN]),
pascal_next_row([0|R1], R).

This answer to a code golf has the implementation in prolog, just expand the names:

The Pascal Triangle is also known as the Tartaglia Triangle:
sumC([X,Y],[Z]) :- Z is X + Y.
sumC([X,Y|L], Z):- H is X + Y,
sumC([Y|L],L2),
Z = [H|L2].
tartaglia(1,[1]) :- ! .
tartaglia(2,[1,1]) :- !.
tartaglia(N, L) :- Ant is N - 1,
tartaglia(Ant,L2),
sumC(L2,R),
append([1|R],[1],L), !.
Using the helper predicate sumC, you can get it easily:
?- tartaglia(3,R).
R = [1, 2, 1].
?- tartaglia(2,R).
R = [1, 1].
?- tartaglia(1,R).
R = [1].
?- tartaglia(6,R).
R = [1, 5, 10, 10, 5, 1].
As said in my comment. You ask for the nth row. [1,2,1] from your example is the 3rd row.

Related

How do I fix the following error in my prolog code for the queen problem

I can't figure out why my code isn't working. I want the code to give me possible combinations for N queens on a NxN chessboard. A possible combination would be e.g. [2, 4, 1, 3] for a 4x4 chessboard. Each digit represent the colume the queen is being placed and as we go through the list we go row by row until we reach the last one. So "2" would be place in the first row in colume 2, "4" would be placed in the second row in colume 4 and so on.
When I use the function n_queens it gives me
the follwing error:
ERROR: Arguments are not sufficiently instantiated
The code:
initliste(M,N,[M|Ns]) :- M < N, M1 is M+1, initliste(M1,N,Ns).
initliste(N,N,[N]).
safe([]).
safe([Q|Qs]) :-
\+attack(Q, Qs),
safe(Qs).
attack(X, [Y|Ys]) :-
X =\= Y,
abs(X-Y) =\= L,
L is length([Y|Ys]),
attack(X, Ys).
attack(_, []).
n_queens(N, L) :-
initliste(1,N,Board),
permutation(Board, L),
safe(L).
You try to compare L (in abs(X-Y) =\= L) before binding a value to L (as you do in L is length([Y|Ys])).

Impossible for me to solve: Simple recursion does not take integers for indexing a list....source_sink does not exist?

This recursion should slice IL to IR out of the list Lin and hand result LOut...
slice(_,IL,IR,LOut) :-
IR<IL,
[LOut].
slice(Lin,IL,IR,LOut) :-
nth0(IL,Lin,X),
append(LOut,[X],LOut2),
IK is IL + 1,
slice(Lin,IK,IR,LOut2).
Input / Output:
?- slice([1,2,3,4],2,3,X).
ERROR: source_sink `'3'' does not exist
ERROR: source_sink `'4'' does not exist
X = [] .
I m also new to Prolog, but I think this recursion must somehow work. Also I'm not really known to the error codes in Prolog, but after checking multiple times I just have to give up... I hope you guys can help me.
slice(_,IL,IR,LOut) :-
IR<IL,
[LOut]. % <-- this line causes source_sink error.
That syntax [name] tries to load the file name.pl as Prolog source code. By the time your code gets there, LOut is [3,4] so it tries to load the files 3.pl and 4.pl, and they don't exist (thankfully, or else who knows what they could do).
I think this recursion must somehow work
It won't; you are appending to a list as you go down into the recursion, which means you will never see the result.
The following might be a close version which works, at least one way:
slice(_,IL,IR,[]) :-
IR < IL.
slice(Lin,IL,IR,[X|LOut]) :-
IR >= IL,
nth0(IL,Lin,X),
IK is IL + 1,
slice(Lin,IK,IR,LOut).
?- slice([0,1,2,3,4,5,6,7,8,9], 2, 5, X).
X = [2, 3, 4, 5]
See how [X|LOut] in the second rule's header puts X in the result that you get, and append/3 is not needed, and LOut finishes down in the recursion eventually as [] the empty list from the first rule, and all the X's are prepended on the front of it to make the result on the way down into the recursion, which is tail recursion, so it doesn't need to go back up, only forward, since there's nothing left to be done after the recursive call.
Since the "cons" is done before the recursion, this is known as "tail recursion modulo cons" in other languages, but in Prolog it is just tail, and the list is being built top-down on the way forward, as opposed to being built bottom up on the way back:
Lin=[0,1,2,3,4,5,6,7,8,9], slice( Lin, 2, 5, R)
:-
nth0(2,Lin,X2), R=[X2|R2], slice( Lin, 3, 5, R2)
:-
nth0(3,Lin,X3), R2=[X3|R3], slice( Lin, 4, 5, R3)
:-
nth0(4,Lin,X4), R3=[X4|R4], slice( Lin, 5, 5, R4)
:-
nth0(5,Lin,X5), R4=[X5|R5], slice( Lin, 6, 5, R5)
:-
R5 = [].
I think findall/3 provides a readable readable solution for your problem:
slice(Lin,IL,IR,LOut) :-
findall(E,(nth0(P,Lin,E),between(IL,IR,P)),LOut).
yields
?- slice([1,2,3,4],2,3,X).
X = [3, 4].
If you expect a different outcome, use standard arithmetic comparison operators (=<,>=) instead of between/3.
I think you want:
list_elems_slice(Start, End, Lst, Slice) :-
list_elems_slice_(Lst, 1, Start, End, Slice).
list_elems_slice_([H|T], N, N, End, [H|Slice]) :-
list_elems_slice_capture_(T, N, End, Slice).
list_elems_slice_([_|T], N, Start, End, Slice) :-
N1 is N + 1,
list_elems_slice_(T, N1, Start, End, Slice).
list_elems_slice_capture_(_, N, N, []).
list_elems_slice_capture_([H|T], N, End, [H|Slice]) :-
N1 is N + 1,
list_elems_slice_capture_(T, N1, End, Slice).
Result in swi-prolog:
?- list_elems_slice(S, E, [a,b,c], Slice).
S = E, E = 1,
Slice = [a] ;
S = 1,
E = 2,
Slice = [a, b] ;
S = 1,
E = 3,
Slice = [a, b, c] ;
S = E, E = 2,
Slice = [b] ;
S = 2,
E = 3,
Slice = [b, c] ;
S = E, E = 3,
Slice = [c] ;
false.
Assuming that the point of this exercise is to teach you to think recursively, I would approach the problem as follows.
To get what you want is essentially two separate operations:
You first must discard some number of items from the beginning of the list, and then
Take some number of items from what's left over
That gives us discard/3:
discard( Xs , 0 , Xs ) .
discard( [_|Xs] , N , Ys ) :- N > 0 , N1 is N-1, discard(Xs,N1,Ys) .
and take/3, very nearly the same operation:
take( _ , 0 , [] ) .
take( [X|Xs] , N , [Y|Ys] ) :- N > 0 , N1 is N-1, take(Xs,N1,Ys) .
Once you have those two simple predicates, slice/4 itself is pretty trivial:
%
% slice( List , Left, Right, Sublist )
%
slice( Xs, L, R, Ys ) :- % to slice a list,
L =< R, % - the left offset must first be less than or equal to the right offset
N is R-L, % - compute the number of items required, and then
discard(Xs,L,X1), % - discard the first L items, and
take(X1,N,Ys). % - take the next N items
. % Easy!
Another approach would be to use append/3:
slice( Xs , L, R, Ys ) :-
length(Pfx,L), % - construct of list of the length to be discarded
append(Pfx,Sfx,Xs), % - use append to split Xs
N is R-L, % - compute the number of items required
length(Ys,N), % - ensure Ys is the required length
append(Ys,_,Sfx) % - use append to split off Ys
. % Easy!

Prolog: decompose number into its digits

I am studying prolog and I am faced with a problem that I cannot deal with.
Given a number, I have to check if the sum of the factorial of each digit that composes it is equal to the number itself.
Example:
145
1! + 4! + 5! = 1 + 24 + 120
Now my problem is just how to decompose the number so that I can factorial and sum each digit.
EDIT1.
thank to #slago I understand how decompose the number, but now I have a problem to sum the factorial terms:
fact(N):-
fact(N, N, _ListNumber).
fact(N, 0, ListNumber):-
factorial(ListNumber, 1, Sum),
Sum == N.
fact(N, Number, [D|R]):-
D is Number mod 10,
Number1 is Number div 10,
fact(N, Number1, R).
factorial([], Counter, Counter).
factorial([D|R], Counter, Sum):-
print([D|R]),
checksum(D, Counter),
factorial(R, Counter, Sum).
checksum(D, Counter):-
Counter1 is Counter * D,
M is D - 1,
M >= 2, !,
checksum(M, Counter1).
I have tried like this, but I noticed [D|R] results empty, and I don't understand why.
Your code is organized in a very confusing way. It is best to code independent predicates (for more specific purposes) and, after that, use them together to get the answer you want.
Start by creating a predicate to decompose a natural number into digits.
decompose(N, [N]) :- N<10, !.
decompose(N, [D|R]) :- N>=10, D is N mod 10, M is N//10, decompose(M, R).
Example of decomposition:
?- decompose(145, D).
D = [5, 4, 1].
Then, create a predicate to compute the factorial of a natural number.
fact(N, F) :- fact(N, 1, F).
fact(0, A, A) :- !.
fact(N, A, F) :- N>0, M is N-1, B is N*A, fact(M, B, F).
Example of factorial:
?- fact(5, F).
F = 120.
After that, create a predicate to map each number of a list into its corresponding factorial (alternatively, you could use the predefined predicate maplist/3).
map_fact([], []).
map_fact([X|Xs], [Y|Ys]) :- fact(X,Y), map_fact(Xs, Ys).
Example of mapping:
?- decompose(145, D), map_fact(D, F).
D = [5, 4, 1],
F = [120, 24, 1].
You must also create a predicate to compute the sum of the items of a list (alternatively, you could use the predefined predicate sum_list/2).
sum(L, S) :- sum(L, 0, S).
sum([], A, A).
sum([X|Xs], A, S) :- B is A+X, sum(Xs, B, S).
Example of summation:
?- decompose(145, D), map_fact(D, F), sum(F, S).
D = [5, 4, 1],
F = [120, 24, 1],
S = 145.
Finally, create the predicate to check the desired number property.
check(N) :- decompose(N, D), map_fact(D, F), sum(F, N).
Example:
?- check(145).
true.
?- check(146).
false.

How to sum up multiple lists in Prolog?

I am working on a prolog program, but I have no idea to finish the program. Here is the requirement.
The program allows multiple fact, however, the length of list in each fact must equals
Example 1
%fact
f(first, [1, 6, 10]).
f(second, [7, 3, 8]).
f(third, [5, 9, 5]).
Example 2
%fact
f(first, [1,6,10]).
f(second, [7,3,8]).
f(third, [5,9,5]).
f(fourth, [7,3,9]).
f(fifth, [7,7,2]).
Example 3
%fact
f(first, [1,6,10,54,11,6]).
f(second, [7,3,8,34,2,7]).
Now, I need to write a predicate sum_list(), so that users can do the following things.
Example 1
?-sum_list([first,second,third], Even, Result).
Even = 1
Result = [13,18,23]
Example 2
?-sum_list([first,second,third,fourth,fifth], Even, Result).
Even = 2
Result = [27,28,34]
Example 3
?-sum_list([first,second], Even, Result).
Even = 3
Result = [8,9,18,88,13,13]
Result is a list which contains the sum of each element in the corresponding fact lists.
Even is counting the number of even number in the Result, in Example 2, only 28 and 34 are even, so Even = 2.
Thanks.
Thanks for SimoV8's hints, and I get some ideas to solve in the way:
%fact
f(first, [1, 6, 10]).
f(second, [7, 3, 8]).
sum_list([Head|Tail], E, R) :-
f(Head, P),
sw(P, Tail, [R]),
even(E,R).
sw(H1, [Head|Tail], [X|R]) :-
f(Head,S),
sum(H1, S, X),
sw(X, Tail, R).
sw(_, [], []).
sum([H1|T1],[H2|T2],[X|L3]) :-
sum(T1,T2,L3), X is H1+H2.
sum([],[],[]).
even(E, [X|R]) :-
even(E2, R),
((X mod 2) =:= 1 -> E is E2; E is E2 + 1).
even(0, []).
However, the answer only accepts two f(), if more than two f(), it will return FALSE
Try this:
sum_list([], 0, []).
sum_list([H|T], E, [RH|RT]):- f(H, X),
sum(X, RH),
sum_list(T, E2, RT),
((RH mod 2) =:= 1 -> E is E2; E is E2 + 1).
sum([], 0).
sum([H|T], S1):- sum(T, S2), S1 is H + S2.

Getting the product of a list from left to right

How do you get the product of a list from left to right?
For example:
?- product([1,2,3,4], P).
P = [1, 2, 6, 24] .
I think one way is to overload the functor and use 3 arguments:
product([H|T], Lst) :- product(T, H, Lst).
I'm not sure where to go from here.
You can use library(lambda) found here : http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/lambda.pl
Quite unreadable :
:- use_module(library(lambda)).
:- use_module(library(clpfd)).
product(L, R) :-
foldl(\X^Y^Z^(Y = []
-> Z = [X, [X]]
; Y = [M, Lst],
T #= X * M,
append(Lst, [T], Lst1),
Z = [T, Lst1]),
L, [], [_, R]).
Thanks to #Mike_Hartl for his advice, the code is much simple :
product([], []).
product([H | T], R) :-
scanl(\X^Y^Z^( Z #= X * Y), T, H, R).
seems like a list copy, just multiplying by last element handled. Let's start from 1 for the leftmost element:
product(L, P) :-
product(L, 1, P).
product([X|Xs], A, [Y|Ys]) :-
Y is X * A,
product(Xs, Y, Ys).
product([], _, []).
if we use library(clpfd):
:- [library(clpfd)].
product([X|Xs], A, [Y|Ys]) :-
Y #= X * A,
product(Xs, Y, Ys).
product([], _, []).
it works (only for integers) 'backward'
?- product(L, [1,2,6,24]).
L = [1, 2, 3, 4].
Probably very dirty solution (I am new to Prolog):
product([ListHead|ListTail], Answer) :-
product_acc(ListTail, [ListHead], Answer).
product_acc([ListHead|ListTail], [AccHead|AccTail], Answer) :-
Product is ListHead * AccHead,
append([Product, AccHead], AccTail, TempList),
product_acc(ListTail, TempList, Answer).
product_acc([], ReversedList, Answer) :-
reverse(ReversedList, Answer).
So basically at the beginning we call another predicate which has
extra "variable" Acc which is accumulator list.
So we take out head (first number) from original list and put it in
to Accumulator list.
Then we always take head (first number) from original list and
multiply it with head (first number) from accumulator list.
Then we have to append our new number which we got by multiplying
with the head from accumulator and later with the tail
Then we call same predicate again until original list becomes empty
and at the end obviously we need to reverse it.
And it seems to work
?- product([1,2,3,4], L).
L = [1, 2, 6, 24].
?- product([5], L).
L = [5].
?- product([5,4,3], L).
L = [5, 20, 60].
Sorry if my explanation is not very clear. Feel free to comment.

Resources