tags:

views:

330

answers:

3

I'm trying to match a subset of the facts I'm creating, and my testcase was working great!

x([1,2,3,4],'bleah').
x([1,2,4],'bleah2').
x([1,2],'bleah8').
x([1,3,4],'bleah3').
x([5,6,7,8],'bleah5').
x([6,7,8,9],'bleah6').

fuzzy(X,R) :- x(Z, R),  subset(X,Z) .
remaining(X,Y,D,M) :- x(Z,D) , select(X,Z,N), select(Y,N,M).
pair(X,Y,R) :- x([X,Y],R) ; x([Y,X],R).

Output:
?- x([1,2|REST],D).
REST = [3, 4],
D = bleah ;
REST = [4],
D = bleah2 ;
REST = [],
D = bleah8 ;
false.

?- pair(2,1,D).
D = bleah8 ;
false.

?- fuzzy([2,1],R).
R = bleah ;
R = bleah2 ;
R = bleah8 ;
false.

?- remaining(2,1,D,M).
D = bleah,
M = [3, 4] ;
D = bleah2,
M = [4] ;
D = bleah8,
M = [] ;
false.

Then I added a fact to represent my next potential case, and now it's quite broken. I'm new to Prolog, I'm not sure why this is or how to fix it.

x([6,X,8,9],'woot') :- (X+0) > 7.

Output:
?- x([1,2|REST],D).
REST = [3, 4],
D = bleah ;
REST = [4],
D = bleah2 ;
REST = [],
D = bleah8 ;
false.

?- pair(2,1,D).
D = bleah8 ;
false.

?- fuzzy([2,1],R).
R = bleah ;
R = bleah2 ;
R = bleah8 ;
ERROR: >/2: Arguments are not sufficiently instantiated
^  Exception: (9) _G260+0>7 ? abort
% Execution Aborted

?- remaining(2,1,D,M).
D = bleah,
M = [3, 4] ;
D = bleah2,
M = [4] ;
D = bleah8,
M = [] ;
ERROR: >/2: Arguments are not sufficiently instantiated
^  Exception: (10) _G270+0>7 ? abort
% Execution Aborted

?- x([_,15,_,_],D).
D = woot.

Suggestions welcome.

+1  A: 

In fuzzy/2 and remaining/4, you are calling x/2 with an uninstantiated Z. This means that the Left Hand Side of + (and therefore >) is uninstantiated.

Paul Butcher
Unfortunately I think this may invalidate this method of searching my facts. Would you suggest any workarounds, or am I going to have to re-evaluate my model?
Demosthenex
+1  A: 

Can X only be a natural number? If yes, then you can change your rule

x([6,X,8,9], 'woot') :- (X+0) > 7.

to

x([6, X, 8, 9], 'woot') :- between(8, inf, X).

This works at least in SWI-Prolog:

?- x(A, B).
A = [6, 8, 8, 9],
B = woot ;
A = [6, 9, 8, 9],
B = woot ;
A = [6, 10, 8, 9],
B = woot ;
...
Kaarel
Eventually it will be a test against a series of facts I've enumerated (ie: less(a,b), less(b,c) -> less(a,c)). I was using numbers as placeholders while I tested the concept. I'll give it a try with another datatype because my enumeration should limit the list of choices.
Demosthenex
A: 
Demosthenex