I have a rule that checks whether a thing is big enough:
big_enough(X) :- size(X,Y), Y #> 2.
If the size of a thing a
is not specified, I want the answer to the query ?- big_enough(a).
to be a model containing size(a, Y | {Y #> 2})
for some variable Y. Therefore, I want that everything has every size until it is stated to have a specific size. Then, it should have this size and no other. Here is my attempt:
size(X,Y) :- has_size(X,Y).
size(X,Y) :- not -size(X,Y).
-size(X,Y1) :- has_size(X,Y2), Y1 \= Y2.
In order to avoid ending up in a loop, the “stating a thing to have a specific size” is done indirectly through the predicate has_size
.
Querying (in ciao) ?- big_enough(a).
gives the model
{ big_enough(a), size(a,Var0 | {Var0 #> 2}), not -size(a,Var0 | {Var0 #> 2}), not -size(Var1,Var2) }.
It contains size(a,Var0 | {Var0 #> 2})
as expected. I don’t understand why it contains not -size(Var1,Var2)
.
When the size of “a” is specified through the fact
size(a,3).
I expect the answer to the query ?- big_enough(a).
to be exactly one model. However, I get two nearly identical models:
{ big_enough(a), size(a,3), has_size(a,3), not -size(Var0 | {Var0 \= a},Var1), not has_size(Var0 | {Var0 \= a},Var2), not -size(a,3), not has_size(a,Var3 | {Var3 \= 3}), -size(a,Var4 | {Var4 \= 3}), not size(a,Var4 | {Var4 \= 3}), not has_size(a,Var4 | {Var4 \= 3}) }
{ big_enough(a), size(a,3), not -size(a,3), not has_size(a,Var0 | {Var0 \= 3}), has_size(a,3), not -size(Var1 | {Var1 \= a},Var2), not has_size(Var1 | {Var1 \= a},Var3), not has_size(a,Var4 | {Var4 \= 3}), -size(a,Var5 | {Var5 \= 3}), not size(a,Var5 | {Var5 \= 3}), not has_size(a,Var5 | {Var5 \= 3}) }
Can someone help me understand this behaviour? I would also appreciate tips on better ways to do this.
Thanks in advance!