Prolog tail recursive helper predicate for power - math

I am trying to make a tail recursive helper for power predicate in Prolog. So far I have this but when testing I get a message saying there is a breakpoint when trying to call helper predicate. What am I doing wrong? Ty for the help.
trpow(Base, Exp, Res) :- trpow_helper(Base, Exp, 1, Res).
trpow_helper(_, 0, Acc, Acc).
trpow_helper(Base, Exp, Acc, Res) :-
Exp > 0,
Decexp is Exp - 1,
Acc1 is Acc * Base,
Res = Acc1,
trpow_helper(Base, Decexp, Acc1, Res).

Based on your code,
trpow(Base, Exp, Res) :- trpow_helper(Base, Exp, 1, Res).
trpow_helper(_, 0, Acc, Acc):- !. /*Cut to avoid bt to second clause*/
trpow_helper(Base, Exp, Acc, Res) :-
Exp > 0,
Decexp is Exp - 1,
Acc1 is Acc * Base, /*removed Res = Acc1, not needed*/
trpow_helper(Base, Decexp, Acc1, Res).
It now works !

Using CLP such as that in swi-prolog:
:- use_module(library(clpfd)).
trpow(Base, Exp, Res) :- trpow_helper(Base, Exp, 1, Res).
trpow_helper( _, Exp, Acc, Acc):- Exp #= 0.
trpow_helper(Base, Exp, Acc, Res) :-
Exp #> 0,
Decexp #= Exp - 1,
Acc1 #= Acc * Base,
trpow_helper(Base, Decexp, Acc1, Res).
?- trpow(1, E, 1).
E = 0 ;
E = 1 .
?- trpow(2, E, 4).
E = 2 .
?- trpow(2, E, 8).
E = 3 .
?- trpow(B, 3, 8).
B = 2 .
?- trpow(B, E, 8).
B = 8,
E = 1 ;
B = 2,
E = 3 ;
...
After which, more solutions that doesn't instanciate B. In fact it loops forever.

Related

Function to display nth element of a list, is returning false.

I have a function I am using to return the nth element of a list.
dispnth([H|T], 0, H).
dispnth([H|T], C, Result) :-
dispnth(T, NewC, H), NewC is C -1.
With an input like
dispnth([1, 2, 3, 4], 2, X).
I should get
X=2.
But I am getting false.
Any ideas?
Check your last line :
dispnth([H|T], 0, H).
dispnth([H|T], C, Result) :-
dispnth(T, NewC, H), NewC is C -1.
Should be
dispnth([H|T], 0, H).
dispnth([H|T], C, Result) :-
Newc is C - 1,
dispnth(T, Newc, Result).

List of Nth prime numbers Prolog

I'm trying to learn prolog and now I'm trying to print a list of the Nth primenumber:
primes(N, N).
primes(N, F):-
prime(F),
write(F), nl,
NewF is F + 1,
primes(N, NewF).
primes(N):-
primes(N, 2).
Prime/1 checks wheter the given number is a prime.
The output for primes(10) will be 2, 3 where it should be 2, 3, 5, 7, because when the NewF after 3 (which will be 4) is not a prime. So it will also not execute the write(F) nor the recursive call. I wondered how I could fix this, so it will not write F when it's not a prime but still execute the part after that. Thanks in advance!
You could simply add the clause:
primes(N, F):-
\+prime(F), nl,
NewF is F + 1,
primes(N, NewF).
I know that this answer doesn't exactly respond to the OP question (my getPrimeList(N, L) create a list L with all prime number from zero to N; the OP ask for first N prime numbers) but... just for fun... I've tried to implement the Sieve of Eratosthenes.
getListDisp(Top, Val, []) :-
Val > Top.
getListDisp(Top, V0, [V0 | Tail]) :-
V0 =< Top,
V1 is V0+2,
getListDisp(Top, V1, Tail).
reduceList(_, _, [], []).
reduceList(Step, Exclude, [Exclude | Ti], Lo) :-
NextE is Exclude+Step,
reduceList(Step, NextE, Ti, Lo).
reduceList(Step, Exclude, [H | Ti], [H | To]) :-
Exclude > H,
reduceList(Step, Exclude, Ti, To).
reduceList(Step, Exclude, [H | Ti], [H | To]) :-
Exclude < H,
NextE is Exclude+Step,
reduceList(Step, NextE, Ti, To).
eratSieve([], []).
eratSieve([Prime | Ti], [Prime | To]) :-
Step is 2*Prime,
Exclude is Prime+Step,
reduceList(Step, Exclude, Ti, Lo),
eratSieve(Lo, To).
getPrimeList(Top, []) :-
Top < 2.
getPrimeList(Top, [2 | L]) :-
Top >= 2,
getListDisp(Top, 3, Ld),
eratSieve(Ld, L).
I repeat: not really an answer; just for fun (as the OP, I'm trying to learn Prolog).

How to count all even numbers in a list

Please help me with how to count even numbers in a list in Prolog. I am a beginner, just started learning Prolog yesterday. I know to count the elements in the list is
mylen([H|Lc],N) :- mylen(Lc,M),N is M+1.
mylen([],0).
And I think defining even number maybe helpful in this case, and I guess the code is maybe something like:
even(n):-
N rem 2 =:= 0.
Can you help me with putting these two parts together, so my code counts even numbers? I know I also need to add a counter, but I have no idea of how to do this in Prolog.
Thank you so very much for you help!
Currently, you have two rules:
(1) The number of elements in the empty list is 0
my_len([], 0).
(2) The number of elements in the list [H|Lc] is N if the number of elements in the list Lc is M and N is M+1
my_len([H|Lc], N) :- my_len(Lc, M), N is M+1.
You're already armed with a predicate which is true if a number is even, and false if it is not: N is even if the remainder of N when divided by 2 is 0:
even(N) :- N rem 2 =:= 0.
Now you can piece it together. The number of even elements in an empty list is still zero. So you keep rule (1). Your rule (2) will need to change as it will need to check if the head of the list is even. You can do this with with two rules in Prolog which take care of the two different cases (the list head is even, or the list head is odd):
(2a) The number of even elements in list [H|Lc] is N if H is even, and the number of even elements in list Lc is M, and N is M+1.
(2b) The number of even elements in list [H|Lc] is N if H is not even (or H is odd), and the number of even elements in list Lc is N. [Notice that N doesn't change if H is odd.]
I'll leave the rendering of these two rules into Prolog as an exercise. You can use the Prolog negation functor, \+ to test if a number is not even, by \+ even(N). Or you can define an odd(N) :- N rem 2 =:= 1. predicate to use for that case.
If your Prolog system offers clpfd, you can use the meta-predicate tcount/3 in combination with even_truth/2. Here's how:
?- tcount(even_truth, [1,2,3,5,7,9,10], N_even).
N_even = 2.
Both predicates (tcount/3 and even_truth/2) are monotone and preserve logical-purity! This makes them very robust and enables you
to always get logically sound answers.
Consider the following more general query:
?- Xs = [_,_,_], tcount(even_truth, Xs, N_even).
Xs = [_A,_B,_C], N_even = 0, _A mod 2 #= 1, _B mod 2 #= 1, _C mod 2 #= 1 ;
Xs = [_A,_B,_C], N_even = 1, _A mod 2 #= 1, _B mod 2 #= 1, _C mod 2 #= 0 ;
Xs = [_A,_B,_C], N_even = 1, _A mod 2 #= 1, _B mod 2 #= 0, _C mod 2 #= 1 ;
Xs = [_A,_B,_C], N_even = 2, _A mod 2 #= 1, _B mod 2 #= 0, _C mod 2 #= 0 ;
Xs = [_A,_B,_C], N_even = 1, _A mod 2 #= 0, _B mod 2 #= 1, _C mod 2 #= 1 ;
Xs = [_A,_B,_C], N_even = 2, _A mod 2 #= 0, _B mod 2 #= 1, _C mod 2 #= 0 ;
Xs = [_A,_B,_C], N_even = 2, _A mod 2 #= 0, _B mod 2 #= 0, _C mod 2 #= 1 ;
Xs = [_A,_B,_C], N_even = 3, _A mod 2 #= 0, _B mod 2 #= 0, _C mod 2 #= 0.

Decompression of a list in prolog

I need to decompress a list in prolog , like in the example below :
decode([[a,1],[b,2],[c,1],[d,3]],L).
L = [a, b, b, c, d, d, d] ;
I made this code :
divide(L,X,Y):-length(X,1),append(X,Y,L).
divide2(L,X,Y):-divide(L,[X|_],[Y|_]).
makelist(_,N,[]):- N =< 0 .
makelist(X,Y,[X|Result]):-Y1 is Y-1,makelist(X,Y1,Result).
makelist2(L,L2):-divide2(L,X,Y),makelist(X,Y,L2).
decode([],[]).
decode([H|T],L):-makelist2(H,H2),append(H2,L,L2),decode(T,L2).
and when i call
makelist2([a,3],L2).
L2 = [a,a,a].
but when i call
decode([[a,3],[b,1],[c,4]],L)
runs continuously. What am i doing wrong ?
Another variation of the theme, using a slightly modified version of Boris' repeat/3 predicate:
% True when L is a list with N repeats of X
repeat([X, N], L) :-
length(L, N),
maplist(=(X), L).
decode(Encoded, Decoded) :-
maplist(repeat, Encoded, Expanded),
flatten(Expanded, Decoded).
If Encode = [[a,1],[b,2],[c,1],[d,3]], then in the above decode/2, the maplist/3 call will yield Expanded = [[a],[b,b],[c],[d,d,d]], and then the flatten/2 call results in Decoded = [a,b,b,c,d,d,d].
In SWI Prolog, instead of flatten/2, you can use append/2 since you only need a "flattening" at one level.
EDIT: Adding a "bidirectional" version, using a little CLPFD:
rle([], []).
rle([X], [[1,X]]).
rle([X,Y|T], [[1,X]|R]) :-
X \== Y, % use dif(X, Y) here, if available
rle([Y|T], R).
rle([X,X|T], [[N,X]|R]) :-
N #= N1 + 1,
rle([X|T], [[N1,X]|R]).
This will yield:
| ?- rle([a,a,a,b,b], L).
L = [[3,a],[2,b]] ? ;
(1 ms) no
| ?- rle(L, [[3,a],[2,b]]).
L = [a,a,a,b,b] ? ;
no
| ?- rle([a,a,a,Y,Y,Z], [X, [N,b],[M,c]]).
M = 1
N = 2
X = [3,a]
Y = b
Z = c ? a
no
| ?- rle([A,B,C], D).
D = [[1,A],[1,B],[1,C]] ? ;
C = B
D = [[1,A],[2,B]] ? ;
B = A
D = [[2,A],[1,C]] ? ;
B = A
C = A
D = [[3,A]] ? ;
(2 ms) no
| ?- rle(A, [B,C]).
A = [D,E]
B = [1,D]
C = [1,E] ? ;
A = [D,E,E]
B = [1,D]
C = [2,E] ? ;
A = [D,E,E,E]
B = [1,D]
C = [3,E] ? ;
...
| ?- rle(A, B).
A = []
B = [] ? ;
A = [C]
B = [[1,C]] ? ;
A = [C,D]
B = [[1,C],[1,D]] ? ;
...
As #mat suggests in his comment, in Prolog implementations that have dif/2, then dif(X,Y) is preferable to X \== Y above.
The problem is in the order of your append and decode in the last clause of decode. Try tracing it, or even better, trace it "by hand" to see what happens.
Another approach: see this answer. So, with repeat/3 defined as:
% True when L is a list with N repeats of X
repeat(X, N, L) :-
length(L, N),
maplist(=(X), L).
You can write your decode/2 as:
decode([], []).
decode([[X,N]|XNs], Decoded) :-
decode(XNs, Decoded_rest),
repeat(X, N, L),
append(L, Decoded_rest, Decoded).
But this is a slightly roundabout way to do it. You could define a difference-list version of repeat/3, called say repeat/4:
repeat(X, N, Reps, Reps_back) :-
( succ(N0, N)
-> Reps = [X|Reps0],
repeat(X, N0, Reps0, Reps_back)
; Reps = Reps_back
).
And then you can use a difference-list version of decode/2, decode_1/3
decode(Encoded, Decoded) :-
decode_1(Encoded, Decoded, []).
decode_1([], Decoded, Decoded).
decode_1([[X,N]|XNs], Decoded, Decoded_back) :-
repeat(X, N, Decoded, Decoded_rest),
decode_1(XNs, Decoded_rest, Decoded_back).
?- decode([[a,1],[b,2],[c,1],[d,3]],L).
L = [a, b, b, c, d, d, d].
?- decode([[a,3],[b,1],[c,0],[d,3]],L).
L = [a, a, a, b, d, d, d].
?- decode([[a,3]],L).
L = [a, a, a].
?- decode([],L).
L = [].
You can deal with both direction with this code :
:- use_module(library(lambda)).
% code from Pascal Bourguignon
packRuns([],[]).
packRuns([X],[[X]]).
packRuns([X|Rest],[XRun|Packed]):-
run(X,Rest,XRun,RRest),
packRuns(RRest,Packed).
run(Var,[],[Var],[]).
run(Var,[Var|LRest],[Var|VRest],RRest):-
run(Var,LRest,VRest,RRest).
run(Var,[Other|RRest],[Var],[Other|RRest]):-
dif(Var,Other).
%end code
pack_1(In, Out) :-
maplist(\X^Y^(X = [V|_],
Y = [V, N],
length(X, N),
maplist(=(V), X)),
In, Out).
decode(In, Out) :-
when((ground(In); ground(Out1)),pack_1(Out1, In)),
packRuns(Out, Out1).
Output :
?- decode([[a,1],[b,2],[c,1],[d,3]],L).
L = [a, b, b, c, d, d, d] .
?- decode(L, [a,b,b,c,d,d,d]).
L = [[a, 1], [b, 2], [c, 1], [d, 3]] .
a compact way:
decode(L,D) :- foldl(expand,L,[],D).
expand([S,N],L,E) :- findall(S,between(1,N,_),T), append(L,T,E).
findall/3 it's the 'old fashioned' Prolog list comprehension facility
decode is a poor name for your predicate: properly done, you predicate should be bi-directional ā€” if you say
decode( [[a,1],[b,2],[c,3]] , L )
You should get
L = [a,b,b,c,c,c].
And if you say
decode( L , [a,b,b,c,c,c] ) .
You should get
L = [[a,1],[b,2],[c,3]].
So I'd use a different name, something like run_length_encoding/2. I might also not use a list to represent individual run lengths as [a,1] is this prolog term: .(a,.(1,[]). Just use a simple term with arity 2 ā€” myself, I like using :/2 since it's defined as an infix operator, so you can simply say a:1.
Try this on for size:
run_length_encoding( [] , [] ) . % the run-length encoding of the empty list is the empty list.
run_length_encoding( [X|Xs] , [R|Rs] ) :- % the run-length encoding of a non-empty list is computed by
rle( Xs , X:1 , T , R ) , % - run-length encoding the prefix of the list
run_length_encoding( T , Rs ) % - and recursively run-length encoding the remainder
. % Easy!
rle( [] , C:N , [] , C:N ) . % - the run is complete when the list is exhausted.
rle( [X|Xs] , C:N , [X|Xs] , C:N ) :- % - the run is complete,
X \= C % - when we encounter a break
. %
rle( [X|Xs] , X:N , T , R ) :- % - the run continues if we haven't seen a break, so....
N1 is N+1 , % - increment the run length,
rle( Xs, X:N1, T, R ) % - and recurse down.
. % Easy!
In direct answer to the original question of, What am I doing wrong?...
When I ran the original code, any expected use case "ran indefinitely" without yielding a result.
Reading through the main predicate:
decode([],[]).
This says that [] is the result of decoding []. Sounds right.
decode([H|T],L) :- makelist2(H,H2), append(H2,L,L2), decode(T,L2).
This says that L is the result of decoding [H|T] if H2 is an expansion of H (which is what makelist2 does... perhaps - we'll go over that below), and H2 appended to this result gives another list L2 which is the decoded form of the original tail T. That doesn't sound correct. If I decode [H|T], I should (1) expand H, (2) decode T giving L2, then (3) append H to L2 giving L.
So the corrected second clause is:
decode([H|T], L) :- makelist2(H, H2), decode(T, L2), append(H2, L2, L).
Note the argument order of append/3 and that the call occurs after the decode of the tail. As Boris pointed out previously, the incorrect order of append and the recursive decode can cause the continuous running without any output as append with more uninstantiated arguments generates a large number of unneeded possibilities before decode can succeed.
But now the result is:
| ?- decode([[a,3]], L).
L = [a,a,a] ? ;
L = [a,a,a,a] ? ;
...
If you try out our other predicates by hand in the Prolog interpreter, you'll find that makelist2/2 has an issue:
It produces the correct result, but also a bunch of incorrect results. Let's have a look at makelist2/2. We can try this predicate by itself and see what happens:
| ?- makelist2([a,3], L).
L = [a,a,a] ? ;
L = [a,a,a,a] ? ;
...
There's an issue: makelist2/2 should only give the first solution, but it keeps going, giving incorrect solutions. Let's look closer at makelist/2:
makelist2(L,L2) :- divide2(L,X,Y), makelist(X,Y,L2).
It takes a list L of the form [A,N], divides it (via divide2/3) into X = A and Y = N, then calls an auxiliary, makelist(X, Y, L2).
makelist(_,N,[]):- N =< 0 .
makelist(X,Y,[X|Result]):-Y1 is Y-1,makelist(X,Y1,Result).
makelist/3 is supposed to generate a list (the third argument) by replicating the first argument the number of times given in the second argument. The second, recursive clause appears to be OK, but has one important flaw: it will succeed even if the value of Y is less than or equal to 0. Therefore, even though a correct solution is found, it keeps succeeding on incorrect solutions because the base case allows the count to be =< 0:
| ?- makelist(a,2,L).
L = [a,a] ? ;
L = [a,a,a] ? ;
We can fix makelist/2 as follows:
makelist(_,N,[]):- N =< 0 .
makelist(X,Y,[X|Result]):- Y > 0, Y1 is Y-1, makelist(X,Y1,Result).
Now the code will generate a correct result. We just needed to fix the second clause of decode/2, and the second clause of makelist/3.
| ?- decode([[a,3],[b,4]], L).
L = [a,a,a,b,b,b,b]
yes
The complete, original code with just these couple of corrections looks like this:
divide(L, X, Y) :- length(X, 1), append(X, Y, L).
divide2(L, X, Y) :- divide(L, [X|_], [Y|_]).
makelist(_, N, []) :- N =< 0 .
makelist(X, Y, [X|Result]) :- Y > 0, Y1 is Y-1, makelist(X,Y1,Result).
makelist2(L, L2) :- divide2(L, X, Y), makelist(X, Y, L2).
decode([], []).
decode([H|T], L) :- makelist2(H,H2), decode(T,L2), append(H2,L2,L).
Note some simple, direct improvements. The predicate, divide2(L, X, Y) takes a list L of two elements and yields each, individual element, X and Y. This predicate is unnecessary because, in Prolog, you can obtain these elements by simple unification: L = [X, Y]. You can try this right in the Prolog interpreter:
| ?- L = [a,3], L = [X,Y].
L = [a,3]
X = a
Y = 3
yes
We can then completely remove the divide/3 and divide2/3 predicates, and replace a call to divide2(L, X, Y) with L = [X,Y] and reduce makelist2/2 to:
makelist2(L, L2) :- L = [X, Y], makelist(X, Y, L2).
Or more simply (because we can do the unification right in the head of the clause):
makelist2([X,Y], L2) :- makelist(X, Y, L2).
You could just remove makelist2/2 and call makelist/2 directly from decode/2 by unifying H directly with its two elements, [X, N]. So the original code simplifies to:
makelist(_, N, []) :- N =< 0 .
makelist(X, Y, [X|Result]) :- Y > 0, Y1 is Y-1, makelist(X,Y1,Result).
decode([], []).
decode([[X,N]|T], L) :- makelist(X, N, H2), decode(T, L2), append(H2, L2, L).
And makelist/3 can be performed a bit more clearly using one of the methods provided in the other answers (e.g., see Boris' repeat/3 predicate).

Creating an iterative function in SML

I've been stuck on this problem for a while now, and can't think of how to solve it.
Consider the following function f : N ā†’ N .
f(0) = 2, f(1) = 0, f(2) = 3,
f(n) = 3f(n-3) + 2f(n-2) - f(n-1) for nā‰„3.
Define an iterative version of f.
I know my solution should look something like this
fun myFun 0 = 2
| myFun 1 = 0
| myFun 2 = 3
| myFun n =
let
(* code *)
in
funHelp(3,2,0,n)
end ;
I know iterative functions are only suppose to use one recursive call, while letting the arguments do all the work. I can't figure out how to do it with this problem, though! Any help would be much appreciated!
I assume this is homework, so I just give you a partial solution:
fun f n =
let
fun iter(0, n0, n1, n2) = n0
| iter(1, n0, n1, n2) = n1
| iter(2, n0, n1, n2) = n2
| iter(n, n0, n1, n2) = iter(n - 1, n1, n2, ???)
in
iter(n, 2, 0, 3)
end
Filling in the ??? shouldn't be too hard.
fun funHelp 0 = (2,0,3)
| funHelp n = let val (x,y,z) = funHelp n - 1
in
(y,z,(3 * x) + (2 * y) - z)
end
fun myFun n = let val (x,_,_) = funHelp n
in
x
end
This should do what you seem to want, if a bit messily.

Resources