Prolog predicate without using lists - recursion

I am required to write a prolog predicate count(X,Y,D,N) without using lists that should count the number of elements between two integers X and Y inclusive. However, it should only count those values that are divisible by D.
For example, count(3,6,2,N) should return N = 2 because 4 and 6 are divisible by 2, but 3 and 5 are not.

Recursion is your friend here (as is the case with most things Prolog).
A helper predicate that takes an additional parameter that acts as an accumulator is useful here:
Something like this should do you:
count( X, Y, D, N ) :- count( X, Y, D, 0, N ) .
count( X , Y , D , T , N ) :- X =< Y, % If X <= Y ...
( X rem D =:= 0 % - and X is divisible by D
-> T1 is T+1 % - then increment T
; T1 = T % - otherwise don't
), % and
X1 is X+1, % - increment X
count( X1, Y, D, T1, N ). % - recurse down
count( X , Y , _ , N , N ) :- X > Y. % IF X > Y, we're done: unify the accumulator with the result.
The above is tail-recursive and is for all intents and purposes optimized into iteration. The more classic recursive solution is something like this:
count( X, Y, _, 0 ) :- X > Y .
count( X, Y, D, N ) :- X =< Y ,
X1 is X+1,
count( X1, Y, D, T ),
( 0 =:= X rem D -> N is T+1 ; N = T )
.

Related

What is causing an infinite recursion? (Prolog)

I'm trying to approach a problem in which given M and N integers, returns in res a list with the powers of M that are less than or equal to N, in descending order.
example: powers(3,9,res).
res = [9,3,1]
My approach is as follows:
power(X,0,1).
power(X,Y,Z) :- X>0,
Yminus1 is Y - 1,
power(X,Yminus1,Z1),
Z is X*Z1.
increment(X,newX) :- newX is X + 1.
powers(M,N,res) :- integer(M), integer(N),
powersAux(M,N,0,res).
powersAux(M,N,E,res) :- power(M,E,Z),
Z=<N,
increment(E,E1),
res1 = [Z|res],
powersAux(M,N,E1,res1).
I'm getting my memory stack filled so I understand that the recursion never ends.
You need to handle special cases:
0n is always 0
1n is always 1
And Prolog has an in-built exponiation function: **/2.
A common Prolog idiom is to have a public predicate that does little outside of constraint validation, that invokes an "internal" helper predicate that does the work. The helper predicate often takes additional parameters that maintain state needed for computation.
That leads to this:
powers( X , L, Ps ) :-
non_negative_integer(X),
non_negative_integer(L),
powers(X,0,L,[],Ps)
.
non_negative_integer(X) :- integer(X), X >= 0 .
% ---------------------------------------------------------------
%
% powers( +Base, +Exponent, +Limit, +Accumulator, ?Results )
%
% where Base and Radix are guaranteed to be non-negative integers
% ---------------------------------------------------------------
powers( 0 , _ , _ , _ , [0] ) :- ! . % 0^n is always 0
powers( 1 , _ , 0 , _ , [] ) :- ! . % 1^n is always 1
powers( 1 , _ , L , _ , [1] ) :- L >= 1 , !. % 1^n is always 1
powers( X , Y , L , Ps , Ps ) :- X**Y > L , !. % when x^y exceeds the limit, we're done, and
powers( X , Y , L , Ts , Ps ) :- % otherrwise...
T is X**Y , % - compute T as x^y
Y1 is Y+1, % - increment Y
powers(X,Y1,L,[T|Ts],Ps) % - recurse down, prepending T to the accumulator list.
. % Easy!
Which gives us
?- powers(2,1024,Ps).
Ps = [1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1]

Error: Unclassifiable statement at (1) in Fortran

i'm not very good at programming but unfortunately it'a compulsory i learn it, moving on i have been asked to do an assignment on programming for vectors.
i have to work out the dot product and the dot product
i got this far:
REAL :: x , y , z
END TYPE myvector
CONTAINS
TYPE ( myvector ) FUNCTION vect_add (a , b )
IMPLICIT NONE
TYPE ( myvector ) , INTENT (IN) :: a , b
vect_add % x = a % x + b % x
vect_add % y = a % y + b % y
vect_add % z = a % z + b % z
END FUNCTION vect_add
TYPE ( myvector ) FUNCTION vect_scale ( vector , scalar )
IMPLICIT NONE
TYPE ( myvector ) , INTENT (IN) :: vector
REAL , INTENT (IN) :: scalar
vect_scale % x = vector % x * scalar
vect_scale % y = vector % y * scalar
vect_scale % z = vector % z * scalar
END FUNCTION vect_scale
TYPE ( myvector ) FUNCTION vect_sub (a , b )
IMPLICIT NONE
TYPE ( myvector ) , INTENT (IN) :: a , b
vect_sub % x = a % x - b % x
vect_sub % y = a % y - b % y
vect_sub % z = a % z - b % z
END FUNCTION vect_sub
REAL FUNCTION vect_dot (a , b )
IMPLICIT NONE
REAL, INTENT(IN) :: a, b
vect_dot % x = a % x * b % x
vect_dot % y = a % y * b % y
vect_dot % z = a % z * b % z
END FUNCTION vect_dot
TYPE ( myvector ) FUNCTION vect_cross (a , b )
IMPLICIT NONE
TYPE ( myvector ) , INTENT (IN) :: a , b
vect_cross % x = (a % x * b % y) - (b % x * a % y)
vect_cross % y = (a % y * b % z) - (b % y * a % z)
vect_cross % z = (a % z + b % x) - (a % x * b % z)
END FUNCTION vect_cross
end program assign_9_2
when i compile it, i get an error message saying: Error:
assign_9_2.f90:42.1:
vect_dot % x = (a % x * b % x)
1
Error: Unclassifiable statement at (1)
assign_9_2.f90:43.1:
vect_dot % y = (a % y * b % y)
1
Error: Unclassifiable statement at (1)
assign_9_2.f90:44.1:
vect_dot % z = (a % z * b % z)
1
Error: Unclassifiable statement at (1)
can someone please help me know where i've gone wrong thank you.
Your function vect_dot is REAL and not TYPE(my_vect) and the arguments a and b are too.

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).

Translating Roman numerals into Arabic ones

I have built a predicate, which converts Roman numerals into Arabic ones. The only problem is that the predicate is limited: if I want to convert more than 3 Arabic numerals at once it does not work anymore.
This is how the predicate should work:
?- convert([v,i,i],Arabic).
Arabic = 7.
My solution so far:
tran([],0).
tran(i,1).
tran(v,5).
tran(x,10).
convert([],X) :- X is 0, !.
convert([T],X) :- tran(T,E), X is E,!.
convert([T|Ts],X) :- tran(T,E), tran(Ts,Es), X is E+Es,!.
convert([T,Ts,Tss],X) :- tran(T,E), tran(Ts,Es), tran(Tss,Ess), X is E+Es+Ess.
I know why the predicate does not work with more than 3 numerals and I could also expand the convert-predicate, but with the same pattern as shown above.
How can I make the convert-predicate more "general" (so that it could work independently of the number of numerals)? Or do you have other ideas how to write the predicate?
Thanks :)
I haven't tested this too much, but I've tried it on several numbers and it seems to work.
The code obeys "subtractive pair rule", described, for example, at https://projecteuler.net/about=roman_numerals
The code uses "accumulator" technique to pass information what was the sum of digits seen before. Initial call just sets the accumulator to 0.
digit(i, 1).
digit(v, 5).
digit(x, 10).
digit(l, 50).
digit(c, 100).
digit(d, 500).
digit(m, 1000).
convert(Roman, Arabic) :-
convert(Roman, 0, Arabic).
convert([], Acc, Acc).
convert([A], Acc, Arabic) :-
digit(A, AVal),
Arabic is Acc + AVal.
convert([A, B | Rest], Acc, Arabic) :-
digit(A, AVal), digit(B, BVal),
AVal < BVal,
NewAcc is Acc + BVal - AVal,
convert(Rest, NewAcc, Arabic).
convert([A, B | Rest], Acc, Arabic) :-
digit(A, AVal), digit(B, BVal),
AVal >= BVal,
NewAcc is Acc + AVal,
convert([B | Rest], NewAcc, Arabic).
Some tests:
convert([v, i, i], Arabic).
Arabic = 7
?- convert([x, i, x], Arabic).
Arabic = 19
?- convert([m, d, c, v, i], Arabic).
Arabic = 1606
It's probably possible to write a predicate convert that works both ways in true Prolog spirit using constraint programming, but I haven't tried this approach.
It might help if you consider the number of discrete "digits" in the Roman numbering system is more than just I, X and V, viz:
roman( "M" , 1000 ) .
roman( "CM" , 900 ) .
roman( "D" , 500 ) .
roman( "CD" , 400 ) .
roman( "C" , 100 ) .
roman( "XC" , 90 ) .
roman( "L" , 50 ) .
roman( "XL" , 40 ) .
roman( "X" , 10 ) .
roman( "IX" , 9 ) .
roman( "V" , 5 ) .
roman( "IV" , 4 ) .
roman( "I" , 1 ) .
Then you can write something like
roman_to_decimal( R , D ) :-
roman_to_decimal( R , 0 , D )
.
roman_to_decimal( [] , D , D ) :- .
roman_to_decimal( R , T , D ) :-
roman(P,V) ,
append(P,S,R) ,
! ,
T1 is T+V ,
roman_to_decimal(S,T1,D)
.
Invoke it as
roman_to_decimal( "MCM" , D ) .
This does have some shortcomings, to whit:
It doesn't enforce syntax: the Roman numbering system required the discrete components to be ordered left-to-right in descending order of value. This doesn't take that into consideration.
It doesn't take into account the many variations. Should 999 be represented as the compact IM or as the rather more verborse CMXCIX?
Just to add a variant to the mix, this version uses the scheme in Sergey's answer (which also allows more arbitrary subtractive sequences), and allows a more human-readable input like Nicholas' answer.
numeral('I', 1).
numeral('V', 5).
numeral('X', 10).
numeral('L', 50).
numeral('C', 100).
numeral('D', 100).
numeral('M', 1000).
r2n(R, N) :-
char_code(A, R),
lower_upper(A, C),
numeral(C, N).
trans(R, N) :-
maplist(r2n, R, Rn), % Pre-calculate a numeric list representation
trans(Rn, 0, N).
trans([X,Y|T], Acc, N) :-
X >= Y,
Acc1 is Acc + X,
trans([Y|T], Acc1, N).
trans([X,Y|T], Acc, N) :-
X < Y,
Acc1 is Acc - X,
trans([Y|T], Acc1, N).
trans([X], Acc, N) :-
N is Acc + X.
trans([], N, N). % Optional rule: needed only if you want trans("", 0). to succeed
Note these rules will allow any valid Roman numeral, but will also do something with and succeed on some improperly formed Roman numerals. So it is not a set of rules to validate proper Roman numerals.
Sample output:
| ?- trans("mmxiv", X).
X = 2014 ? ;
no
| ?- trans("CMXCIX", X).
X = 999 ? ;
no
| ?- trans("IM", X).
X = 999 ? ;
no
| ?- trans("IVX", X). % Not a properly-formed Roman numeral
X = 4 ? ; % Uh... ok... I guess
no

Problems with Tail Recursion and reversing list?

Hello I have a call like this list of digits(436,L).
How can I reverse the list, and make it tail recursive??
list_of_digits(0,[]).
list_of_digits(M, [Z|Zx]) :- M > 0 ,
MM is floor(M / 10),
Z is M mod 10,
list_of_digits(MM,Zx).
Can anyone help me please??
I want to transform my number, in this case 436 into
a List like [4,3,6].
I call ?- list_of_digits(436,L)
and get
L = [6,3,4] ;
false.
back.
Using an accumulator:
list_of_digits(X,L) :- lod_acc(X, [], L).
lod_acc(0,R,R).
lod_acc(M,Acc,R) :-
M > 0,
MM is floor(M / 10),
Z is M mod 10,
lod_acc(MM,[Z|Acc],R).
I'd do it this way, to deal with negative numbers and with zero itself (a special case):
%
% the external/public API predicate.
%
% this handles the special case of zero, which has 1 digit.
% all other cases are handled by the internal worker predicate.
%
digits_in( X , Ds ) :- int(X) , X > 0 , digits_in(X,[],Ds).
digits_in( X , Ds ) :- int(X) , X < 0 , Y is abs(X) , digits_in(Y,[],Ds).
digits_in( 0 , [0] ) .
%
% the internal/private guts-of-the-operation predicate
%
digits_in( 0 , Ds , Ds ). % when we hit zero, we're done.
digits_in( X , Ts , Ds ) :- % otherwise...
T is X mod 10 , % get the lower order digit via modulus arithmetic
X1 is X // 10 , % get the high order digits via integer division
digits_in( X1 , [T|Ts] , Ds ) % [tail-]recurse down.
.

Resources