prolog - recursive predicate sum(J,K,N) - recursion
I'm trying to solve the exercise from book "Prolog Programming In Depth".
Define a recursive predicate sum(J,K,N) that instantiates N to the sum of the integers from J to K inclusive:
?- sum(-1,1,What).
What = 0
?- sum(1,3,What).
What = 6
?- sum(6,7,What).
What = 13
My predicate is below.
sum(J, K, N) :- sum_iter(J, K, N, J, 0). % clause_1
sum_iter(J, K, N, I, S) :- % clause_2
Kn is K+1, % clause_X
I = Kn,
N = S,!.
sum_iter(J, K, N, I, S) :- % clause_2, I - index, S - SumTmp
I =< K,
NewI is I+1,
NewS is S+I,
sum_iter(J, K, N, NewI, NewS).
It works correctly but I don't understand:
why I should use clause_X (why +1)
and why I can't replace clause_2 by
sum_iter(J, K, N, K, N) :- !.
In this case predicate stops work on previous step.
For example, expect:
?- sum(1,3,What).
What = 6
BUT Prolog output:
?- sum(1,3,What).
What = 3
Printing out some of the state:
sum(J, K, N) :- sum_iter(J, K, N, J, 0).
% the rule at the end of the recursion
sum_iter(J, K, N, I, S) :-
format("rule 1: J=~w K=~w N=~w I=~w S=~w\n", [J, K, N, I, S]),
Kn is K+1,
I = Kn,
format("...pos 1 passed\n"),
N = S,
format("...pos 2 passed\n"),
!.
% the rule perfoming the recursion
sum_iter(J, K, N, I, S) :-
format("rule 2: J=~w K=~w N=~w I=~w S=~w\n", [J, K, N, I, S]),
I =< K,
format("...pos 3 passed\n"),
NewI is I+1,
NewS is S+I,
sum_iter(J, K, N, NewI, NewS).
?- sum(1,3,What).
rule 1: J=1 K=3 N=_11338 I=1 S=0
rule 2: J=1 K=3 N=_11338 I=1 S=0
...pos 3 passed
rule 1: J=1 K=3 N=_11338 I=2 S=1
rule 2: J=1 K=3 N=_11338 I=2 S=1
...pos 3 passed
rule 1: J=1 K=3 N=_11338 I=3 S=3
rule 2: J=1 K=3 N=_11338 I=3 S=3
...pos 3 passed
rule 1: J=1 K=3 N=_11338 I=4 S=6
...pos 1 passed
...pos 2 passed
What = 6.
At the end, the I = Kn becomes a test: both I and Kn are
set to actual values, with I one "past the end".
You could do this, using an I > K "guard":
sum_iter(_, K, Res, I, Res) :- I > K,!.
But what you also want to do this:
Call the recursive rule by default, if it is applicable.
If it is not, call the "end of recursion rule".
So a rearrangement is best:
sum(J, K, N) :- sum_iter(J, K, N, J, 0).
% the rule perfoming the recursion, with a guard "I =< K", which, once
% successful, commits the computation to this one rule, so we add "!"
sum_iter(J, K, N, I, S) :-
format("rule 2: J=~w K=~w N=~w I=~w S=~w\n", [J, K, N, I, S]),
I =< K,!,
format("...pos 3 passed\n"),
NewI is I+1,
NewS is S+I,
sum_iter(J, K, N, NewI, NewS).
% the rule at the end of the recursion, also with guard:
sum_iter(J, K, Res, I, Res) :-
format("end: J=~w K=~w I=~w Res=~w\n", [J, K, I, Res]),
I > K,!.
Actually, there is no need for the "cut" in the second
rule, because it is the last rule. There is no need for the
guard in this case either, it is just the negation of the guard in
the first rule. But let's leave both for clarity.
?- sum(1,3,What).
rule 2: J=1 K=3 N=_15630 I=1 S=0
...pos 3 passed
rule 2: J=1 K=3 N=_15630 I=2 S=1
...pos 3 passed
rule 2: J=1 K=3 N=_15630 I=3 S=3
...pos 3 passed
rule 2: J=1 K=3 N=_15630 I=4 S=6
end: J=1 K=3 I=4 Res=6
What = 6.
Related
Conditioning and writing down an equation over a known set of combinations
I'm trying to write a constraint in the from of the following (also attached): sum([s,i], x[i,j,s,p] ) = sum([s,k], x[j,k,s,p] ) for all j in N\{0,n}, p in P I already have all possible combinations of (i,j,s,p) stored in a set Xs and X0nswhich a vector of such 4-tuples. Thus I tried to write it down as #constraint( model, [p in P, jj in X0ns], sum(x[(i, j, s, p)] for (i, j, s, p) in Xs if j == jj) == sum(x[(j, k, s, p)] for (i, j, s, p) in Xs if j == jj) This gives me an Error. On top of that I think this is not correct way of writing. Because I did not include a summation on S anywhere. Is it needed? How can I build this kind of constraint?
Here is what I think that you mean (this is the exact implementation of your LaTeX equation). Normally you should not have used tuples for array indexing. m = Model(); S=1:3 N=1:4 K=1:4 P=1:5 #variable(m, x[N,N,S,P] >= 0); #constraint(m, [j in N[2:end-1], p in P], sum(x[i,j,s,p] for i in N, s in S) == sum(x[j,k,s,p] for k in K, s in S))
Goldbach graph using sagemath
I'm learning SageMath (uses Python 3) and playing with the Goldbach conjecture. I wrote this function (it works!): def Goldbach(n): if n % 2 != 0 or n <= 2: show("No és parell") else: for i in srange(n): if is_prime(i): for j in srange(n): if is_prime(j) and i + j == n: a = [i, j] show(a) return Now I'm trying (no idea) to do the following plot: Denoting by r(2k) the number of Goldbach partitions of 2k, the conjecture affirms that r(2k) > 0 if k > 1. I have to do a graph of points (k, r(2k)), k > 2. How could I do it?
First of all, let us get some better implementation in Sage of the routine counting the number r(K) (for K > 2 some even integer) of the solutions for p + q = 2k, p, q prime numbers. We count both solutions (p, q) and (q, p) when they differ. def r(K): if K not in ZZ or K <= 2 or K % 2: return None if K == 4: return 1 count = 0 for p in primes(3, K): for q in primes(3, K + 1 - p): if p + q == K: count += 1 return count goldbach_points = [(K, r(K)) for K in range(4, 100,2)] show(points(goldbach_points)) This gives:
Sum of powers in Prolog
I'm trying to implement a method to work as follows foo(5) = 5^4 + 4^3 + 3^2 + 2^1 + 1^0 = 701 using recursion. I've been trying to follow the logic but I keep getting errors. can someone guide me? (define (foo n) ; size-n problem ( cond ( (= (- n 1) 0 ) ; stopping condition 0 ); return value (else (+ ( expt n (- n 1) ) ( foo (- n 1) ) ) ))) ; size-m problems
If you tagged the question correctly, you want to answer this in Prolog, but your code fragment suggests you use lisp (or a language that I don't know). In Prolog you write predictes. For your problem, there are two cases: The case where N is less than or equal to zero, which is zero: foo(N,0) :- N =< 0, !. The inductive case when N is greater than 0. In that case we calculate foo for N-1 and add up N^(N-1): foo(N,S) :- N1 is N-1, foo(N1,T), S is T+N^N1. You can simply write program containing the two cases: foo(N,0) :- N =< 0, !. foo(N,S) :- N1 is N-1, foo(N1,T), S is T+N^N1. And test it as follows: ?- foo(-1,S). S = 0. ?- foo(0,S). S = 0. ?- foo(1,S). S = 1. ?- foo(2,S). S = 3. ?- foo(3,S). S = 12. ?- foo(5,S). S = 701. You can akso make th is predicate more safer from looping by adding a check for the inductive case: foo(N,0) :- N =< 0, !. foo(N,S) :- N > 0, N1 is N-1, foo(N1,T), S is T+N^N1. Or you can further boost the predicate's performance using an accumulator: foo(N,S) :- foo(N,0,S). foo(N,S,T) :- N > 0, !, N1 is N-1, Q is S+N^N1, foo(N1,Q,T). foo(N,S,S) :- N =< 0. This version also checks first whether N > 0 before N =< 0 because it is a much more likely scenario: after one N =< 0 we stop recursion whereas the N > 0 will be called N-1 times. Using an accumulator enables a optimization technique called tail recursion.
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).
Prolog: count iteration in binary search tree
I have a predicate that get a bst T in input and return a list S of the values contained in the bst that belong to a specific range [R1,R2] and this works fine. When I try to count the iteration done in order to get the list in output I receive Always false. This is my predicate's code: findExamsInRange(R1, R2, T, S, N) :- find(R1, R2, T, S, N), N > 0. find(R1, R2, nil, [], N). find(R1, R2, t(V,L,R), S, N) :- V >= R1, V =< R2, find(R1,R2, L, L,NL), find(R1,R2, R, LR,NR), append([V|LL], LR, S), N is NL+NR+1. find(R1, R2, t(V,L,R), S, N) :- V < R1, find(R1, R2, R, S, N). find(R1, R2, t(V,L,R), S, N) :- V > R2, find(R1, R2, L, S, N). Can anyone help me why I cannot get the value of N?
Shouldn't the first clause of the find/5 predicate: find(R1, R2, nil, [], N). be instead: find(_R1, _R2, nil, [], 0). When reaching the leaves of the tree, you have to return a value for N that allows the N is NL+NR+1 goal to succeed without errors.
You need to use assert and retract to define a global counter : inc_counter:- % normal case retract(counter(X)), !, Y is X+1, assert(counter(Y)). inc_counter:- % if counter is not defined yet assert(counter(1)). You then place inc_counter in the clauses whose iterations you want to count, and query the end result using counter(X).