Related
i have the following
fnf([],[],[]).
fnf([RH|RT],[CH|CT],[[RH,CH]|Res]) :- get(RH,CH,V), V == 0, fnf(RT,CT,Res).
i'm trying to collect only elements of Cs and Rs for which the V is zero.
The code above does that but fails when it hits non-zero value.
I want to just skip them, instead of failing the whole goal.
this sort of works
fnf([RH|RT],[CH|CT],[[RH,CH]|Res]) :- get(RH,CH,V), ( V == 0 -> fnf(RT,CT,Res);true).
still _2044 !! should not be there
F = [[1, 1], [2, 2]|_2044].
If you want to test only once (get/3 + condition) and then keep the item or skip it and continue recursion you can use an if-then-else construct like so:
fnf([], [], []).
fnf([RH|RT], [CH|CT], Res) :-
get(RH, CH, V),
( V==0 % test
-> Res=[[RH, CH]|Res1] % condition met, keep item
; Res=Res1 % condition not met, skip item
),
fnf(RT, CT, Res1).
Also note the call to get/3 may backtrack if it leaves choicepoints.
How about adding a case for 0 and a case for non-zero:
fnf([],[],[]).
fnf([RH|RT],[CH|CT],[[RH,CH]|Res]) :-
get(RH,CH,0),
fnf(RT,CT,Res).
fnf([_|RT],[_|CT],Res) :-
get(RH,CH,V),
dif(V, 0),
fnf(RT,CT,Res).
or
pairs_keys_values(Pairs, Rs, Cs),
findall([RH,CH], (member(RH-CH, Pairs), get(RH, CH, 0)), F).
I tried resolving it by myself in the following way:
list_of_positives(L1, L2) :-
list_of_positives(L1, L2, []).
list_of_positives([], L, L).
list_of_positives([H|T], L2, L3) :-
( H > 0
-> list_of_positives(T,L2,[H|L3])
; list_of_positives(T,L2,L3)
).
The problem with this solution is that I get as response a reversed list of positive numbers. Can someone help me to find a way to get the list in the "correct order"?
You can solve the problem as follows:
positives([], []).
positives([H|T], P) :-
( H > 0
-> P = [H|R] % desired order!
; P = R),
positives(T, R) .
Example:
?- positives([2,-3,6,-7,1,4,-9], P).
P = [2, 6, 1, 4].
You want to use a difference list, a non-closed, or open list. So, something like this:
positives( [] , [] ) . % An empty list has not positives, and closes the list.
positives( [N|Ns] , [N|Rs] ) :- % For a non-empty list, we prepend N to the result list
N > 0, % - if N is positive
positives(Ns,Rs) % - and recurse down.
. %
positives( [N|Ns] , Rs ) :- % For non-empty lists, we discard N
N =< 0, % - if N is non-positive
positives(Ns,Rs) % - and recurse down.
. %
Hello everyone,
The following code does recursive checks. For each call , F gets a value of either 1 or 0 , due to a condition . I want my test_liars predicate return True if all checks had result 1 , and False if at least one call , set F's value to 0.
What test_liars actually does , is not something really eager to explain , but I can if asked.
test_liars should return True to Flag's argument, asked :
test_liars(2,[3,2,1,4,2],[1,0,0,1,0],Flag)
given different list ,rather than [1,0,0,1,0], it must return False
test_liars(_,[],_,_) .
test_liars(N,[HF|TF],[HT|TT],Flag) :-
(HT == 0 -> ( N >= HF -> F = 1 ; F = 0)
; ( N < HF -> F = 1 ; F = 0)),
test_liars(N,TF,TT,Flag),
write(F),
(F == 0 -> Flag = 'True' ; Flag = 'False').
First of all, I think it is more elegant to transform the nested if-then-else structure into a predicate. For instance test_liar/4:
% test_liar(N,HT,HF,F).
test_liar(N,0,HF,1) :-
N >= HF,
!.
test_liar(N,1,HF,1) :-
N < HF,
!.
test_liar(_,_,_,0).
Which makes things easier. Now you can write:
test_liars(_,[],_,_).
test_liars(N,[HF|TF],[HT|TT],Flag) :-
test_liar(N,HT,HF,F),
test_liars(N,TF,TT,Flag),
write(F),
(F == 0 -> Flag = 'True' ; Flag = 'False').
Nevertheless we are not there yet. Your Flag should return 'False' if at least one element is a liar. That means that in the base case, there are no liars, so we should return 'True':
test_liars(_,[],_,'True').
In the inductive case we thus have to construct some kind of "and", like:
custom_and('True',1,'True') :-
!.
custom_and(_,_,'False').
Now we only need to call this custom_and/3 on the outcome of the recursive test_liars and test_liar:
test_liars(N,[HF|TF],[HT|TT],Flag) :-
test_liar(N,HT,HF,F),
test_liars(N,TF,TT,SubFlag),
write(F),
custom_and(SubFlag,F,Flag).
Or now the full code:
test_liar(N,0,HF,1) :-
N >= HF,
!.
test_liar(N,1,HF,1) :-
N < HF,
!.
test_liar(_,_,_,0).
custom_and('True',1,'True') :-
!.
custom_and(_,_,'False').
test_liars(_,[],_,'True').
test_liars(N,[HF|TF],[HT|TT],Flag) :-
test_liar(N,HT,HF,F),
test_liars(N,TF,TT,SubFlag),
write(F),
custom_and(SubFlag,F,Flag).
I'm trying to compare the elements of a list of integer to see if they are ordered (or not). I'm using Amzi!
I gave a few attempts, but nothing works... :(
ordered([X]).
ordered([N|[N1|L]]) :- N <= N1, ordered([N1|L]).
ordered_([X]).
ordered_([Head,Head1|Tail]) :- Head <= Head1, ordered_([Head1|Tail]).
Both return no if this list is entered:
ordered([1,2,3,4]).
ordered_([1,2,3,4]).
I understand that I need to compare the head with the head of the tail.
Doesn't seem like it should be any more complex than
ordered( [] ) .
ordered( [_] ) .
ordered( [X,Y|Z] ) :- X =< Y , ordered( [Y|Z] ) .
Arithmetic comparison predicates are covered here: http://www.amzi.com/manuals/amzi/pro/ref_math.htm#MathematicalComparisons
Use #=</2 or compare/3 to check the ordering of things in the standard order of terms: http://www.amzi.com/manuals/amzi/pro/ref_manipulating_terms.htm#StandardOrder
a compact alternative:
ordered(L) :- \+ ( append(_,[A,B|_], L), A > B ).
More efficient alternative to most upvoted solution, comparing three instead of appending the bigger element back to the list
is_sorted([]).
is_sorted([X, Y, Z|T]) :- X =< Y, Y =< Z, is_sorted(T).
is_sorted([X, Y|T]) :- X =< Y, is_sorted(T).
I'm new to Prolog and I can't seem to get the answer to this on my own.
What I want is, that Prolog counts ever Number in a list, NOT every element. So for example:
getnumbers([1, 2, c, h, 4], X).
Should give me:
X=3
getnumbers([], 0).
getnumbers([_ | T], N) :- getnumbers(T, N1), N is N1+1.
Is what I've got, but it obviously gives me every element in a list. I don't know how and where to put a "only count numbers".
As usual, when you work with lists (and SWI-Prolog), you can use module lambda.pl found there : http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/lambda.pl
:- use_module(library(lambda)).
getnumbers(L, N) :-
foldl(\X^Y^Z^(number(X)
-> Z is Y+1
; Z = Y),
L, 0, N).
Consider using the built-in predicates (for example in SWI-Prolog), and checking their implementations if you are interested in how to do it yourself:
include(number, List, Ns), length(Ns, N)
Stay logically pure, it's easy: Use the meta-predicate
tcount/3 in tandem with the reified type test predicate number_t/2 (short for number_truth/2):
number_t(X,Truth) :- number(X), !, Truth = true.
number_t(X,Truth) :- nonvar(X), !, Truth = false.
number_t(X,true) :- freeze(X, number(X)).
number_t(X,false) :- freeze(X,\+number(X)).
Let's run the query the OP suggested:
?- tcount(number_t,[1,2,c,h,4],N).
N = 3. % succeeds deterministically
Note that this is monotone: delaying variable binding is always logically sound. Consider:
?- tcount(number_t,[A,B,C,D,E],N), A=1, B=2, C=c, D=h, E=4.
N = 3, A = 1, B = 2, C = c, D = h, E = 4 ; % succeeds, but leaves choice point
false.
At last, let us peek at some of the answers of the following quite general query:
?- tcount(number_t,[A,B,C],N).
N = 3, freeze(A, number(A)), freeze(B, number(B)), freeze(C, number(C)) ;
N = 2, freeze(A, number(A)), freeze(B, number(B)), freeze(C,\+number(C)) ;
N = 2, freeze(A, number(A)), freeze(B,\+number(B)), freeze(C, number(C)) ;
N = 1, freeze(A, number(A)), freeze(B,\+number(B)), freeze(C,\+number(C)) ;
N = 2, freeze(A,\+number(A)), freeze(B, number(B)), freeze(C, number(C)) ;
N = 1, freeze(A,\+number(A)), freeze(B, number(B)), freeze(C,\+number(C)) ;
N = 1, freeze(A,\+number(A)), freeze(B,\+number(B)), freeze(C, number(C)) ;
N = 0, freeze(A,\+number(A)), freeze(B,\+number(B)), freeze(C,\+number(C)).
of course, you must check the type of an element to see if it satisfies the condition.
number/1 it's the predicate you're looking for.
See also if/then/else construct, to use in the recursive clause.
This uses Prolog's natural pattern matching with number/1, and an additional clause (3 below) to handle cases that are not numbers.
% 1 - base recursion
getnumbers([], 0).
% 2 - will pass ONLY if H is a number
getnumbers([H | T], N) :-
number(H),
getnumbers(T, N1),
N is N1+1.
% 3 - if got here, H CANNOT be a number, ignore head, N is unchanged, recurse tail
getnumbers([_ | T], N) :-
getnumbers(T, N).
A common prolog idiom with this sort of problem is to first define your predicate for public consumption, and have it invoke a 'worker' predicate. Often it will use some sort of accumulator. For your problem, the public consumption predicate is something like:
count_numbers( Xs , N ) :-
count_numbers_in_list( Xs , 0 , N ) .
count_numbers_in_list( [] , N , N ) .
count_numbers_in_list( [X|Xs] , T , N ) :-
number(X) ,
T1 is T+1 ,
count_numbers_in_list( Xs , T1 , N )
.
You'll want to structure the recursive bit so that it is tail recursive as well, meaning that the recursive call depends on nothing but data in the argument list. This allows the compiler to reuse the existing stack frame on each call, so the predicate becomes, in effect, iterative instead of recursive. A properly tail-recursive predicate can process a list of infinite length; one that is not will allocate a new stack frame on every recursion and eventually blow its stack. The above count_numbers_in_list/3 is tail recursive. This is not:
getnumbers([H | T], N) :-
number(H),
getnumbers(T, N1),
N is N1+1.