Program for finding all X lists in Prolog

I am starting to learn Prolog. This program tries to get all occurrences of this element:

occurences(_, [], Res):- Res is []. occurences(X, [X|T], Res):- occurences(X,T,TMP), Res is [X,TMP]. occurences(X, [_|T], Res):- occurences(X,T,Res). 

But here is the error:

 ?- occurences(a,[a,b,c,a],Res). ERROR: is/2: Arithmetic: `[]/0' is not a function ^ Exception: (11) _G525 is [] ? creep Exception: (10) occurences(a, [], _G524) ? creep Exception: (9) occurences(a, [a], _G524) ? creep Exception: (8) occurences(a, [c, a], _G524) ? creep Exception: (7) occurences(a, [b, c, a], _G524) ? creep Exception: (6) occurences(a, [a, b, c, a], _G400) ? creep 
+4
recursion prolog prolog-dif runtime-error
Dec 01 '12 at 18:01
source share
3 answers

In addition to what others wrote, consider using the dif / 2 constraint:

 occurrences(_, [], []). occurrences(X, [X|Ls], [X|Rest]) :- occurrences(X, Ls, Rest). occurrences(X, [L|Ls], Rest) :- dif(X, L), occurrences(X, Ls, Rest). 

Now you can use the predicate in all directions, for example:

 ?- occurrences(X, [a,a,b], Os). X = a, Os = [a, a] ; X = b, Os = [b] ; Os = [], dif(X, b), dif(X, a), dif(X, a) ; false. 

The last solution means that the list of entries is empty if X differs from a and b .

+5
01 Dec
source share

Rubens already informed you of your mistake. I'll just add a note to the style: often in Prolog, he preferred to directly encode the template in the chapter arguments:

 occurences(_, [], []). occurences(X, [X|T], [X|TMP]) :- occurences(X,T,TMP), !. occurences(X, [_|T], Res) :- occurences(X,T,Res). 

I adjusted the second sentence of 'output' from [X,TMP] to [X|TMP] and note the reduction: without it, the procedure produces more results than required:

 ?- occurences(a,[a,b,c,a],Res). Res = [a, a] ; Res = [a] ; Res = [a] ; Res = [] ; false. 

with a cut:

 ?- occurences(a,[a,b,c,a],Res). Res = [a, a]. 

edit @false messed up the nasty bug: here's the fix using the if / then / else construct

 occurences(_, [], []). occurences(X, [Y|T], Os) :- ( X = Y -> Os = [X|R] ; Os = R ), occurences(X,T,R). 
+1
Dec 01
source share

Consider:

 occurrences(_, [], []) :- !. occurrences(X, [Y|L], R) :- X \== Y, !, occurrences(X, L, R). occurrences(X, [Y|L], [Y|R]) :- occurrences(X, L, R). 

Testing:

 ?- occurrences(a,[a,b,a,c],O). O = [a, a]. ?- occurrences(a,[a,X,a,c],O). O = [a, a]. ?- occurrences(a,[a,X,a,c],[a]). false. ?- occurrences(a,[a,X,a,c],[a,a]). true. 
0
Dec 12
source share



All Articles