Prolog - Not returning desired Variable - prolog

I realised that my first question was too long and no one would understand it.
Here is the link to a condensed simpler question that exhibits my problem in a shorter program.
[Condened Question Link] Prolog - Not returning desired value
==================================================================================
I am trying to write a Brainf*ck interpreter in Prolog.
The function bf will take 3 strings. Only relevant parts of the code is as follows:
%Prog - string of BF program
%Input- string of inputs for the BF program
%Output - what the BF program will output
bf(Prog, Input,Output):- run(Prog, Input, Output).
run(Prog, Input, Output) :-
create_mem(Mem),
iterateBF(Prog,[],Mem,0, Input, Output).
%start by creating the memory space
create_mem(Memory) :-
var(Memory), %check if it is uninstantiated variable
create_mem(Memory,10000).
create_mem([],0) :- !.
create_mem([0|Tail],Size) :-
NewSize is Size - 1,
create_mem(Tail,NewSize).
%get memory value at ptr location
get_mem([Value|_],Value,0). %base case
get_mem([_|Tail],Value,Ptr) :-
Ptr > 0,
NewPtr is Ptr - 1,
get_mem(Tail,Value,NewPtr).
%for adding a value to memory space
%need to mod with 256 due to the it being 8 bits to get the actual value.
increase_mem([Value|MemTail],[NewValue|MemTail],0) :-
NewValue is (Value + 1) mod 256.
increase_mem([Head|Tail],[Head|NewTail],Ind) :-
Ind > 0,
NewInd is Ind - 1,
increase_mem(Tail,NewTail,NewInd).
%iterateBF(Prog,[],Mem,0, Input, []).
%when reach the end of the the
iterateBF([],_,_,_,_,[]) :- !.
iterateBF([],_,_,_,_,_) :-!.
iterateBF(Instruction,Inst_Iterated,Mem,Ptr,Input,Output) :-
checkInstruction(Instruction,Inst_Iterated,Mem,Ptr,Input,Output,
NewInstruction,NewInst_Iterated,NewMem,NewPtr,NewInput,NewOutput),
iterateBF(NewInstruction,NewInst_Iterated,NewMem,NewPtr,NewInput,NewOutput).
checkInstruction([Plus|ProgTail],Inst_Iterated,Mem,Ptr,Input,Output,ProgTail,Inst_Iterated,NewMem,Ptr,Input,Output) :-
char_code('+',Plus),
increase_mem(Mem,NewMem,Ptr), !.
%get the memory value at ptr
%Put into Output
checkInstruction([Period|ProgTail],Inst_Iterated,Mem,Ptr,Input,Output,ProgTail,Inst_Iterated,Mem,Ptr,Input,NewOutput) :-
char_code('.',Period),
NewOutput = [Output|Value],
get_mem(Mem,Value,Ptr),!.
The above code will compile and only work for:
bf("+.","",Out).
SWI-Prolog will just return true, while I want it to return the value of Out.
Tracing it in SWI, whenever it returns to the call of iterateBF(Prog,[],Mem,0, Input, Output) in run, Output just loses its previous value.
You just need to pay attention to the following functions:
Run
iterateBF
checkInstructions
The rest are just for compilation sake.

your checkInstruction([Plus|ProgTail],Inst_Iterated,Mem,Ptr,Input,Output,ProgTail,Inst_Iterated,NewMem,Ptr,Input,Output) it's way too complex.
And indeed your problem it's that Output doesn't get correctly bound. But instead of a 'banal' correction, what about a general improvement:
Try to comment your code, what you expect it will do, and after done, possibly simplify it as far as possible.

Related

What are some best practices for writing Prolog predicates so that it works in different ways the arguments are specified

I am trying to implement some simple predicates, something like my_length or my_append.
It is considered easy for me if we knew beforehand that we wanted to find the length of a list, or we wanted to append two lists. (i.e. I know what is input, what is output).
In Prolog, it is possible to do thing in other ways. Like my_length(L, 3), or my_append(A,B,[1,2,3]).
Sometimes, my code works. Sometimes, it doesn't.
I find it quite difficult to make sure it works in all sort of different ways. Unless it is just a helper predicate for myself, you never really know what your users want to test it with. Sometimes the problem can even be ill defined, it is unclear what should my_length(L, 5) outputs, for example.
Are there any best practices for that?
For practical programming, I found it much easier to just ignore these other ways and focus on only a particular way of calling. That's how I get things done, I am just worried about the possibility that someone else call it in a different way.
Is there a way for me to make that restriction at the language level? Or should I?
In particular, I am trying to write my_length such that it works for
Specifying list, calculating length, and
Specifying length, give me back a list that has length unbounded slot.
my_length([], 0).
my_length([_|T], A) :- my_length(T, TA), A is TA + 1.
That works fine both ways, except it prompts for more answers when I ask the reverse question, and then we get a stack overflow. We also can't do arithmetic with the length argument since it could be unspecified.
This is just a specific case.
Can use cut (i.e. the exclamation mark):
list_length(Lst, Len) :-
nonvar(Len),
% Commit to this path
!,
% Using an accumulator - faster than recursion
list_length_(Lst, 0, Len),
% No more than 1 solution
!.
list_length(Lst, Len) :-
list_length_(Lst, 0, Len).
% Found end of list
list_length_([], Len, Len).
list_length_([_|T], Upto, Len) :-
% Iterate through list
inc_below_max(Upto, Len, Upto1),
list_length_(T, Upto1, Len).
% Increment, keeping to maximum (if specified)
inc_below_max(I, Max, I1) :-
I1 is I + 1,
( nonvar(Max)
-> I1 =< Max
; true
).
Results in swi-prolog:
?- list_length([a,b,c], Len).
Len = 3.
?- list_length(Lst, 3).
Lst = [_, _, _].
?- Lst = [a,b,c], list_length(Lst, Len).
Len = 3.
?- Lst = [a,b|Tail], list_length(Lst, 1).
false.
This avoids unwanted choicepoints.

How can I verify if a coordinate is in a list

I'm generating random coordinates and adding on my list, but first I need verify if that coordinate already exists. I'm trying to use member but when I was debugging I saw that isn't working:
My code is basically this:
% L is a list and Q is a count that define the number of coordinate
% X and Y are the coordinate members
% check if the coordniate already exists
% if exists, R is 0 and if not, R is 1
createCoordinates(L,Q) :-
random(1,10,X),
random(1,10,Y),
convertNumber(X,Z),
checkCoordinate([Z,Y],L,R),
(R is 0 -> print('member'), createCoordinates(L,Q); print('not member'),createCoordinates(L,Q-1).
checkCoordinate(C,L,R) :-
(member(C,L) -> R is 0; R is 1).
% transforms the number N in a letter L
convertNumber(N,L) :-
N is 1, L = 'A';
N is 2, L = 'B';
...
N is 10, L = 'J'.
%call createCoordinates
createCoordinates(L,20).
When I was debugging this was the output:
In this picture I'm in the firts interation and L is empty, so R should be 1 but always is 0, the coordinate always is part of the list.
I have the impression that the member clause is adding the coordinate at my list and does'nt make sense
First off, I would recommend breaking your problem down into smaller pieces. You should have a procedure for making a random coordinate:
random_coordinate([X,Y]) :-
random(1, 10, XN), convertNumber(XN, X),
random(1, 10, Y).
Second, your checkCoordinate/3 is converting Prolog's success/failure into an integer, which is just busy work for Prolog and not really improving life for you. memberchk/2 is completely sufficient to your task (member/2 would work too but is more powerful than necessary). The real problem here is not that member/2 didn't work, it's that you are trying to build up this list parameter on the way out, but you need it to exist on the way in to examine it.
We usually solve this kind of problem in Prolog by adding a third parameter and prepending values to the list on the way through. The base case then equates that list with the outbound list and we protect the whole thing with a lower-arity procedure. In other words, we do this:
random_coordinates(N, Coordinates) :- random_coordinates(N, [], Coordinates).
random_coordinates(0, Result, Result).
random_coordinates(N, CoordinatesSoFar, FinalResult) :- ...
Now that we have two things, memberchk/2 should work the way we need it to:
random_coordinates(N, CoordinatesSoFar, FinalResult) :-
N > 0, succ(N0, N), % count down, will need for recursive call
random_coordinate(Coord),
(memberchk(Coord, CoordinatesSoFar) ->
random_coordinates(N, CoordinatesSoFar, FinalResult)
;
random_coordinates(N0, [Coord|CoordinatesSoFar], FinalResult)
).
And this seems to do what we want:
?- random_coordinates(10, L), write(L), nl.
[[G,7],[G,3],[H,9],[H,8],[A,4],[G,1],[I,9],[H,6],[E,5],[G,8]]
?- random_coordinates(10, L), write(L), nl.
[[F,1],[I,8],[H,4],[I,1],[D,3],[I,6],[E,9],[D,1],[C,5],[F,8]]
Finally, I note you continue to use this syntax: N is 1, .... I caution you that this looks like an error to me because there is no distinction between this and N = 1, and your predicate could be stated somewhat tiresomely just with this:
convertNumber(1, 'A').
convertNumber(2, 'B').
...
My inclination would be to do it computationally with char_code/2 but this construction is actually probably better.
Another hint that you are doing something wrong is that the parameter L to createCoordinates/2 gets passed along in all cases and is not examined in any of them. In Prolog, we often have variables that appear to just be passed around meaninglessly, but they usually change positions or are used multiple times, as in random_coordinates(0, Result, Result); while nothing appears to be happening there, what's actually happening is plumbing: the built-up parameter becomes the result value. Nothing interesting is happening to the variable directly there, but it is being plumbed around. But nothing is happening at all to L in your code, except it is supposedly being checked for a new coordinate. But you're never actually appending anything to it, so there's no reason to expect that anything would wind up in L.
Edit Notice that #lambda.xy.x solves the problem in their answer by prepending the new coordinate in the head of the clause and examining the list only after the recursive call in the body, obviating the need for the second list parameter.
Edit 2 Also take a look at #lambda.xy.x's other solution as it has better time complexity as N approaches 100.
Since i had already written it, here is an alternative solution: The building block is gen_coord_notin/2 which guarantees a fresh solution C with regard to an exclusion list Excl.
gen_coord_notin(C, Excl) :-
random(1,10,X),
random(1,10,Y),
( memberchk(X-Y, Excl) ->
gen_coord_notin(C, Excl)
;
C = X-Y
).
The trick is that we only unify C with the new result, if it is fresh.
Then we only have to fold the generations into N iterations:
gen_coords([], 0).
gen_coords([X|Xs], N) :-
N > 0,
M is N - 1,
gen_coords(Xs, M),
gen_coord_notin(X, Xs).
Remark 1: since coordinates are always 2-tuples, a list representation invites unwanted errors (e.g. writing [X|Y] instead of [X,Y]). Traditionally, an infix operator like - is used to seperate tuples, but it's not any different than using coord(X,Y).
Remark 2: this predicate is inherently non-logical (i.e. calling gen_coords(X, 20) twice will result in different substitutions for X). You might use the meta-level predicates var/1, nonvar/1, ground/1, integer, etc. to guard against non-sensical calls like gen_coord(1-2, [1-1]).
Remark 3: it is also important that the conditional does not have multiple solutions (compare member(X,[A,B]) and memberchk(X,[A,B])). In general, this can be achieved by calling once/1 but there is a specialized predicate memberchk/2 which I used here.
I just realized that the performance of my other solutions is very bad for N close to 100. The reason is that with diminishing possible coordinates, the generate and test approach will take longer and longer. There's an alternative solution which generates all coordinates and picks N random ones:
all_pairs(Ls) :-
findall(X-Y, (between(1,10,X), between(1,10,Y)), Ls).
remove_index(X,[X|Xs],Xs,0).
remove_index(I,[X|Xs],[X|Rest],N) :-
N > 0,
M is N - 1,
remove_index(I,Xs,Rest,M).
n_from_pool(_Pool, [], 0).
n_from_pool(Pool, [C|Cs], N) :-
N > 0,
M is N - 1,
length(Pool, L),
random(0,L,R),
remove_index(C,Pool,NPool,R),
n_from_pool(NPool, Cs, M).
gen_coords2(Xs, N) :-
all_pairs(Pool),
n_from_pool(Pool, Xs, N).
Now the query
?- gen_coords2(Xs, 100).
Xs = [4-6, 5-6, 5-8, 9-6, 3-1, 1-3, 9-4, 6-1, ... - ...|...] ;
false.
succeeds as expected. The error message
?- gen_coords2(Xs, 101).
ERROR: random/1: Domain error: not_less_than_one' expected, found0'
when we try to generate more distinct elements than possible is not nice, but better than non-termination.

Fold over a partial list

This is a question provoked by an already deleted answer to this question. The issue could be summarized as follows:
Is it possible to fold over a list, with the tail of the list generated while folding?
Here is what I mean. Say I want to calculate the factorial (this is a silly example but it is just for demonstration), and decide to do it like this:
fac_a(N, F) :-
must_be(nonneg, N),
( N =< 1
-> F = 1
; numlist(2, N, [H|T]),
foldl(multiplication, T, H, F)
).
multiplication(X, Y, Z) :-
Z is Y * X.
Here, I need to generate the list that I give to foldl. However, I could do the same in constant memory (without generating the list and without using foldl):
fac_b(N, F) :-
must_be(nonneg, N),
( N =< 1
-> F = 1
; fac_b_1(2, N, 2, F)
).
fac_b_1(X, N, Acc, F) :-
( X < N
-> succ(X, X1),
Acc1 is X1 * Acc,
fac_b_1(X1, N, Acc1, F)
; Acc = F
).
The point here is that unlike the solution that uses foldl, this uses constant memory: no need for generating a list with all values!
Calculating a factorial is not the best example, but it is easier to follow for the stupidity that comes next.
Let's say that I am really afraid of loops (and recursion), and insist on calculating the factorial using a fold. I still would need a list, though. So here is what I might try:
fac_c(N, F) :-
must_be(nonneg, N),
( N =< 1
-> F = 1
; foldl(fac_foldl(N), [2|Back], 2-Back, F-[])
).
fac_foldl(N, X, Acc-Back, F-Rest) :-
( X < N
-> succ(X, X1),
F is Acc * X1,
Back = [X1|Rest]
; Acc = F,
Back = []
).
To my surprise, this works as intended. I can "seed" the fold with an initial value at the head of a partial list, and keep on adding the next element as I consume the current head. The definition of fac_foldl/4 is almost identical to the definition of fac_b_1/4 above: the only difference is that the state is maintained differently. My assumption here is that this should use constant memory: is that assumption wrong?
I know this is silly, but it could however be useful for folding over a list that cannot be known when the fold starts. In the original question we had to find a connected region, given a list of x-y coordinates. It is not enough to fold over the list of x-y coordinates once (you can however do it in two passes; note that there is at least one better way to do it, referenced in the same Wikipedia article, but this also uses multiple passes; altogether, the multiple-pass algorithms assume constant-time access to neighboring pixels!).
My own solution to the original "regions" question looks something like this:
set_region_rest([A|As], Region, Rest) :-
sort([A|As], [B|Bs]),
open_set_closed_rest([B], Bs, Region0, Rest),
sort(Region0, Region).
open_set_closed_rest([], Rest, [], Rest).
open_set_closed_rest([X-Y|As], Set, [X-Y|Closed0], Rest) :-
X0 is X-1, X1 is X + 1,
Y0 is Y-1, Y1 is Y + 1,
ord_intersection([X0-Y,X-Y0,X-Y1,X1-Y], Set, New, Set0),
append(New, As, Open),
open_set_closed_rest(Open, Set0, Closed0, Rest).
Using the same "technique" as above, we can twist this into a fold:
set_region_rest_foldl([A|As], Region, Rest) :-
sort([A|As], [B|Bs]),
foldl(region_foldl, [B|Back],
closed_rest(Region0, Bs)-Back,
closed_rest([], Rest)-[]),
!,
sort(Region0, Region).
region_foldl(X-Y,
closed_rest([X-Y|Closed0], Set)-Back,
closed_rest(Closed0, Set0)-Back0) :-
X0 is X-1, X1 is X + 1,
Y0 is Y-1, Y1 is Y + 1,
ord_intersection([X0-Y,X-Y0,X-Y1,X1-Y], Set, New, Set0),
append(New, Back0, Back).
This also "works". The fold leaves behind a choice point, because I haven't articulated the end condition as in fac_foldl/4 above, so I need a cut right after it (ugly).
The Questions
Is there a clean way of closing the list and removing the cut? In the factorial example, we know when to stop because we have additional information; however, in the second example, how do we notice that the back of the list should be the empty list?
Is there a hidden problem I am missing?
This looks like its somehow similar to the Implicit State with DCGs, but I have to admit I never quite got how that works; are these connected?
You are touching on several extremely interesting aspects of Prolog, each well worth several separate questions on its own. I will provide a high-level answer to your actual questions, and hope that you post follow-up questions on the points that are most interesting to you.
First, I will trim down the fragment to its essence:
essence(N) :-
foldl(essence_(N), [2|Back], Back, _).
essence_(N, X0, Back, Rest) :-
( X0 #< N ->
X1 #= X0 + 1,
Back = [X1|Rest]
; Back = []
).
Note that this prevents the creation of extremely large integers, so that we can really study the memory behaviour of this pattern.
To your first question: Yes, this runs in O(1) space (assuming constant space for arising integers).
Why? Because although you continuously create lists in Back = [X1|Rest], these lists can all be readily garbage collected because you are not referencing them anywhere.
To test memory aspects of your program, consider for example the following query, and limit the global stack of your Prolog system so that you can quickly detect growing memory by running out of (global) stack:
?- length(_, E),
N #= 2^E,
portray_clause(N),
essence(N),
false.
This yields:
1.
2.
...
8388608.
16777216.
etc.
It would be completely different if you referenced the list somewhere. For example:
essence(N) :-
foldl(essence_(N), [2|Back], Back, _),
Back = [].
With this very small change, the above query yields:
?- length(_, E),
N #= 2^E,
portray_clause(N),
essence(N),
false.
1.
2.
...
1048576.
ERROR: Out of global stack
Thus, whether a term is referenced somewhere can significantly influence the memory requirements of your program. This sounds quite frightening, but really is hardly an issue in practice: You either need the term, in which case you need to represent it in memory anyway, or you don't need the term, in which case it is simply no longer referenced in your program and becomes amenable to garbage collection. In fact, the amazing thing is rather that GC works so well in Prolog also for quite complex programs that not much needs to be said about it in many situations.
On to your second question: Clearly, using (->)/2 is almost always highly problematic in that it limits you to a particular direction of use, destroying the generality we expect from logical relations.
There are several solutions for this. If your CLP(FD) system supports zcompare/3 or a similar feature, you can write essence_/3 as follows:
essence_(N, X0, Back, Rest) :-
zcompare(C, X0, N),
closing(C, X0, Back, Rest).
closing(<, X0, [X1|Rest], Rest) :- X1 #= X0 + 1.
closing(=, _, [], _).
Another very nice meta-predicate called if_/3 was recently introduced in Indexing dif/2 by Ulrich Neumerkel and Stefan Kral. I leave implementing this with if_/3 as a very worthwhile and instructive exercise. Discussing this is well worth its own question!
On to the third question: How do states with DCGs relate to this? DCG notation is definitely useful if you want to pass around a global state to several predicates, where only a few of them need to access or modify the state, and most of them simply pass the state through. This is completely analogous to monads in Haskell.
The "normal" Prolog solution would be to extend each predicate with 2 arguments to describe the relation between the state before the call of the predicate, and the state after it. DCG notation lets you avoid this hassle.
Importantly, using DCG notation, you can copy imperative algorithms almost verbatim to Prolog, without the hassle of introducing many auxiliary arguments, even if you need global states. As an example for this, consider a fragment of Tarjan's strongly connected components algorithm in imperative terms:
function strongconnect(v)
// Set the depth index for v to the smallest unused index
v.index := index
v.lowlink := index
index := index + 1
S.push(v)
This clearly makes use of a global stack and index, which ordinarily would become new arguments that you need to pass around in all your predicates. Not so with DCG notation! For the moment, assume that the global entities are simply easily accessible, and so you can code the whole fragment in Prolog as:
scc_(V) -->
vindex_is_index(V),
vlowlink_is_index(V),
index_plus_one,
s_push(V),
This is a very good candidate for its own question, so consider this a teaser.
At last, I have a general remark: In my view, we are only at the beginning of finding a series of very powerful and general meta-predicates, and the solution space is still largely unexplored. call/N, maplist/[3,4], foldl/4 and other meta-predicates are definitely a good start. if_/3 has the potential to combine good performance with the generality we expect from Prolog predicates.
If your Prolog implementation supports freeze/2 or similar predicate (e.g. Swi-Prolog), then you can use following approach:
fac_list(L, N, Max) :-
(N >= Max, L = [Max], !)
;
freeze(L, (
L = [N|Rest],
N2 is N + 1,
fac_list(Rest, N2, Max)
)).
multiplication(X, Y, Z) :-
Z is Y * X.
factorial(N, Factorial) :-
fac_list(L, 1, N),
foldl(multiplication, L, 1, Factorial).
Example above first defines a predicate (fac_list) which creates a "lazy" list of increasing integer values starting from N up to maximum value (Max), where next list element is generated only after previous one was "accessed" (more on that below). Then, factorial just folds multiplication over lazy list, resulting in constant memory usage.
The key to understanding how this example works is remembering that Prolog lists are, in fact, just terms of arity 2 with name '.' (actually, in Swi-Prolog 7 the name was changed, but this is not important for this discussion), where first element represents list item and the second element represents tail (or terminating element - empty list, []). For example. [1, 2, 3] can be represented as:
.(1, .(2, .(3, [])))
Then, freeze is defined as follows:
freeze(+Var, :Goal)
Delay the execution of Goal until Var is bound
This means if we call:
freeze(L, L=[1|Tail]), L = [A|Rest].
then following steps will happen:
freeze(L, L=[1|Tail]) is called
Prolog "remembers" that when L will be unified with "anything", it needs to call L=[1|Tail]
L = [A|Rest] is called
Prolog unifies L with .(A, Rest)
This unification triggers execution of L=[1|Tail]
This, obviously, unifies L, which at this point is bound to .(A, Rest), with .(1, Tail)
As a result, A gets unified with 1.
We can extend this example as follows:
freeze(L1, L1=[1|L2]),
freeze(L2, L2=[2|L3]),
freeze(L3, L3=[3]),
L1 = [A|R2], % L1=[1|L2] is called at this point
R2 = [B|R3], % L2=[2|L3] is called at this point
R3 = [C]. % L3=[3] is called at this point
This works exactly like the previous example, except that it gradually generates 3 elements, instead of 1.
As per Boris's request, the second example implemented using freeze. Honestly, I'm not quite sure whether this answers the question, as the code (and, IMO, the problem) is rather contrived, but here it is. At least I hope this will give other people the idea what freeze might be useful for. For simplicity, I am using 1D problem instead of 2D, but changing the code to use 2 coordinates should be rather trivial.
The general idea is to have (1) function that generates new Open/Closed/Rest/etc. state based on previous one, (2) "infinite" list generator which can be told to "stop" generating new elements from the "outside", and (3) fold_step function which folds over "infinite" list, generating new state on each list item and, if that state is considered to be the last one, tells generator to halt.
It is worth to note that list's elements are used for no other reason but to inform generator to stop. All calculation state is stored inside accumulator.
Boris, please clarify whether this gives a solution to your problem. More precisely, what kind of data you were trying to pass to fold step handler (Item, Accumulator, Next Accumulator)?
adjacent(X, Y) :-
succ(X, Y) ;
succ(Y, X).
state_seq(State, L) :-
(State == halt -> L = [], !)
;
freeze(L, (
L = [H|T],
freeze(H, state_seq(H, T))
)).
fold_step(Item, Acc, NewAcc) :-
next_state(Acc, NewAcc),
NewAcc = _:_:_:NewRest,
(var(NewRest) ->
Item = next ;
Item = halt
).
next_state(Open:Set:Region:_Rest, NewOpen:NewSet:NewRegion:NewRest) :-
Open = [],
NewOpen = Open,
NewSet = Set,
NewRegion = Region,
NewRest = Set.
next_state(Open:Set:Region:Rest, NewOpen:NewSet:NewRegion:NewRest) :-
Open = [H|T],
partition(adjacent(H), Set, Adjacent, NotAdjacent),
append(Adjacent, T, NewOpen),
NewSet = NotAdjacent,
NewRegion = [H|Region],
NewRest = Rest.
set_region_rest(Ns, Region, Rest) :-
Ns = [H|T],
state_seq(next, L),
foldl(fold_step, L, [H]:T:[]:_, _:_:Region:Rest).
One fine improvement to the code above would be making fold_step a higher order function, passing it next_state as the first argument.

generate a range of ints -- "out of local stack" [beginner]

gen(N,R):
R is value between 0 and N-1, in order.
Nnon-zero positive int. N will always be given.
For example: ?- genN(2,R). gives R=0;R=1. I implemented like this, but it has "out of local static error":
gen(X,0).
gen(X,R) :-
gen(X,R1),
R is R1+1,
R<X, % why this line
R>=0. % and this line can't keep the range successfully?
Result:
?- genN2(3,R).
R = 0 ;
R = 1 ;
R = 2 ;
ERROR: Out of local stack
To understand why your program does not terminate, use a failure-slice. To this end, we will insert some extra goals false that help to understand why the goals you added are irrelevant. If this resulting fragment does not terminate, then your original program does not terminate either. As you can see, there is not much happening in that part. In fact your program will terminate never.
gen(_X,0) :- false.
gen(X,R) :-
gen(X,R1), false,
R is R1+1,
R<X,
R>=0.
(There are some more issues: your definition would be true also for a goal like gen(-1,0) which is probably not what you intended.)
The best way to solve this all at once is to use clpfd instead of the more complex to handle (is)/2 or simply to use between/3:
gen(N0, R) :-
N1 is N0-1,
between(0, N1, R).

PROLOG: Check if first list contains 3 times less of each element than second list

I need to check if each element in second list has 3 times more instances then the same element in the first list. My function returns false all the time and I don't know what I'm dong wrong.
Here is the code:
fourth(_,[ ]).
fourth(A,[HF|TF]) :-
intersection(A, HF, NewA),
intersection(TF, HF, NewB),
append(HF, NewB, NewT),
append(NewA, NewA, NewAA),
append(NewA, NewAA, NewAAA),
length(NewAAA) == length(NewT),
select(HF, TF, NewTF),
fourth(A, NewTF).
Example:
?- fourth([1,2,3], [1,1,1]).
true.
?- fourth([1,2,3], [1,1,1,1]).
false.
?- fourth([1,2,3], [1,1]).
false.
?- fourth([1,2,2,3], [1,1,2,2,1,2,2,2,2]).
true.
I would make myself a select/3 predicate: select(X,From,Left), and then for each elt of a first list I'd call it three times with same first argument on a second list, progressively passing it forward, getting me a final Left3 without the three occurences of X; iand I'd do that for each elt of a first list. Then if I'd succeed and end up with an empty list, that means it had exactly three times each elt from the first list.
Your code seems needlessly complicated. It also contains bugs where you use HF instead of the list [HF].
So what's the logic you want to implement?:
take the next element from the second list (leaving the tail)
check if it's in the first list, and if it is, remove it (else fail)
remove it two more times from the tail of the second list
and this gives:
fourth(_,[ ]).
fourth(A,[HF|TF]) :-
once(select(HF, A, AR)), % using once/1 to avoid choicepoints
once(select(HF, TF, TF1)),
once(select(HF, TF1, TFR)),
fourth(AR, TFR).
Here is your code with suggestions on why it fails :
fourth(_,[]).
fourth(A,[HF|TF]) :-
intersection(A, HF, NewA),
intersection(TF, HF, NewB),
It's not intersection/3 that you want to use, for two reasons :
1) it doesn't filter only HF in A.
2) it fails if you call it with an element, so at least use [HF] instead
of HF
Instead, use include/3 : include(=(HF), A, NewA). See SWI-pl doc for more info.
append(HF, NewB, NewT),
append(NewA, NewA, NewAA),
append(NewA, NewAA, NewAAA),
Use of append/2 is better, especially for your NewAAA list.
length(NewAAA) == length(NewT),
You can't compare lengths like that. First, length/1 doesn't exist in
built-in swi-pl predicates. Instead, compare directly the lists or use
length/2 twice and then compare the results.
select(HF, TF, NewTF),
fourth(A, NewTF).
Only removing once HT in TF will cause your algorithm to fail. You need
to remove all the occurrences of HT in TF, with subtract/3 for example...
If you want a working solution respecting your original work, I'll add it, so feel free to ask, but as it was tagged homework I'll let you those working leads first...
% Blocks in our "block world"
%
% b3
% b4 b7
% b1 b5 b8
% b2 b6 b9
%==============
% Block Stacking
on(b1,b2).
on(b3,b4).
on(b4,b5).
on(b5,b6).
on(b7,b8).
on(b8,b9).
% Stack order
left(b2,b6).
left(b6,b9).
% Generalize "above"
above(Above,Below) :- on(Above,Below).
above(Above,Below) :- on(Above,AnyBlock), above(AnyBlock,Below).
% isLeft(X,Y) resolves to true if X is a block left of any block Y.
% isLeft/2 simply invokes leftOf/2 followed by a cut (!) to guarantee that
% only one result is generated.
%
% For Example: isleft(b1,b7) produces true
% isleft(b2,b6) produces true
% isleft(b4,b5) produces false.
% isleft(b9,b3) produces false.
isLeft(X,Y) :- leftOf(X,Y), !.
% Show an implementation of leftOf below. The implementation will involve a
% few cases (like the above predicate above), but can be completed using only the
% provided left and above predicates.

Resources