Can you use CLIPS to run on 3-valued logic? - clips

Running if not X, assert Y with no initial fact resulted in Y.
From this I thought that CLIPS was a 2-valued logic. Is there a way to enable 3-valued logic in CLIPS?

Related

Prolog single-variable query returns an error. Why?

I've created a simple Prolog program (using GNU Prolog v1.4.4) with a single fact:
sunny.
When I run the following query:
sunny.
I get:
yes
As I'd expect. When I run this query:
X.
I get:
uncaught exception: error(instantiation_error,top_level/0)
when I expected to get:
X = sunny
Anyone know why?
Prolog is based on first-order logic but X is a second order logic query (the variable stands for a rule head / fact, not only a term): you ask "which predicates can be derived?" or in other words "which formulas are true?". Second order logic is so expressive that we lose many nice properties of first-order logic (*). That's why a second order variable must be sufficiently instantiated to know which rule to try at the time it is called (that's what the error message means). For instance the queries
?- X=member(A,[1,2,3]), X.
and
?- member(A,[1,2,3]).
still allow Prolog to try the definition of the member predicate (in fact the two definitions are equivalent) but
?- X, X=member(A,[1,2,3]).
will throw an exception because at the time X should be derived, we don't know that it's supposed to become the predicate member(A,[1,2,3]).
Your case is much simpler though: you can wrap sunny as a term into a predicate such that Prolog knows which rules to try. The facts
weather(sunny).
weather(rainy).
define the predicate weather such that now we only have a first-order variable as argument in our query:
?- weather(X).
X = sunny ;
X = rainy.
Now that we are talking about the term level, everything works as you expected.
(*) Although the problem of finding out if a formula is valid is undecidable in both cases, in first order logic at least all true formulas can be eventually derived but if a formula is false, the search might not terminate (i.e. first-order logic is semi-decidable). For second order logic there are formulas that can neither be proved not disproved. What is worse is that we cannot even tell if a second-order formula belongs to this category.

Determining successor in prolog using recursion

I'm trying (failing) to understand an exercise where I'm given the following clauses;
pterm(null).
pterm(f0(X)) :- pterm(X).
pterm(f1(X)) :- pterm(X).
They represent a number in binary, eg. f0(null) is equivalent to 0, f1(null) is equivalent to 1, etc.
The objective is to define a predicate over pterm such that one is the successor of the other when true. It seems like a relatively simple exercise but I'm struggling to get my head around it.
Here is the code I've written so far;
incr(X,Y) :- pterm(f0(X)), pterm(f1(Y)).
incr(X,Y) :- pterm(f0(f1(X))), pterm(f1(f1(Y))).
Having tested this I know it's very much incorrect. How might I go about inspecting the top level arguments of each pterm?
I've made minimal progress in the last 4 hours so any hints/help would be appreciated.
1)
I'll start with the "how to inspect" question, as I think it will be the most useful. If you're using swi-prolog with xpce, run the guitracer:
?- consult('pterm'). % my input file
% pterm compiled 0.00 sec, 5 clauses
true.
?- guitracer.
% The graphical front-end will be used for subsequent tracing
true.
?- trace. % debugs step by step
true.
[trace] ?- pterm(f0(f1(null))). % an example query to trace
true.
A graphical interface will come up. Press the down arrow to unify things step by step. What's going on should make sense fairly quickly.
(use notrace. and nodebug. appropriately to exit trace and debug modes afterwards).
2) You seem to misunderstand how predicates work. A predicate is a logical statement, i.e. it will always return either true or false. You can think of them as classical boolean functions of the type "iseven(X)" (testing if X is even) or "ismemberof(A,B)" (testing if A is a member of B) etc. When you have a rule like "pred1 :- pred2, pred3." this is similar to saying "pred1 will return true if pred2 returns true, and pred3 returns true (otherwise pred1 returns false)".
When your predicates are called using constants, checking its truth value is a matter of checking your facts database to see if that predicate with those constants can be satisfied. But when you call using variables, prolog goes through a wild goose chase, trying to unify that variable with all the allowable stuff it can link it to, to see if it can try to make that predicate true. If it can't, it gives up and says it's false.
A predicate like incr(X,Y) is still something that needs to return true or false, but, if by design, this only becomes true when Y is the incremented version of X, where X is expected to be given at query time as input, then we have tricked prolog into making a "function" that is given X as input, and "returns" Y as output, because prolog will try to find an appropriate Y that makes the predicate true.
Therefore, with your example, incr(X,Y) :- pterm(f0(X)), pterm(f1(Y)). makes no sense, because you're telling it that incr(X,Y) will return true for any X,Y, as long as prolog can use X to find in the fact database any pterm(f0(X)) that will lead to a known fact, and also use Y to find a pterm(f1(Y)) term. You haven't made Y dependent on X in any way. This query will succeed for X = null, and Y = null, for instance.
Your first clause should be something like this.
incr(X,Y) :- X = pterm(f0(Z)), Y = pterm(f1(Z)).
where = performs unification. I.e. "find a value for Z such that X is pterm(f0(Z)), and for the same value of Z it also applies that Y = pterm(f1(Z))."
In fact, this could be more concisely rewritten as a fact:
incr( pterm(f0(Z)), pterm(f1(Z)) ).
3)
Your second clause can be adapted similarly. However, I'm not sure if this is correct in terms of the logic of what you're trying to achieve (i.e. binary arithmetic). But I may have misunderstood the problem you're trying to solve.
My assumption is that if you have (0)111, then the successor should be 1000, not 1111. For this, I would guess you need to create a predicate that recursively checks if the incrementation of the digits below the currently processed one results in a 'carried' digit.
(since the actual logic is what your assignment is about, I won't offer a solution here. but hope this helps get you into grips with what's going on. feel free to have a go at the recursive version and ask another question based on that code!)

Prolog: Can you make a predicate behave differently depending on whether a value is ground or not?

I have a somewhat complex predicate with four arguments that need to work when both the first and last arguments are ground/not ground, not ground/ground or ground/ground, and the second and third arguments are ground.
i.e. predicate(A,B,C,D).
I can't provide my actual code since it is part of an assignment.
I have it mostly working, but am receiving instantiation errors when A is not ground, but D is. However, I have singled out a line of code that is causing issues. When I change the goal order of the predicate, it works when D is ground and A is not, but in doing so, it no longer works for when A is ground and D is not. I'm not sure there is a way around this.
Is there a way to use both lines of code so that if the A is ground for instance it will use the first line, but if A is not ground, it will use the second, and ignore the first? And vice versa.
You can do that, but, almost invariably, you will break the declarative semantics of your programs if you do that.
Consider a simple example to see how such a non-monotonic and extra-logical predicate already breaks basic assumptions and typical declarative properties of well-known predicates, like commutativity of conjunction:
?- ground(X), X = a.
false.
But, if we simply exchange the goals by commutativity of conjunction, we get a different answer:
?- X = a, ground(X).
X = a.
For this reason, such meta-logical predicates are best avoided, especially if you are just beginning to learn the language.
Instead, better stay in the pure and monotonic subset of Prolog. Use constraints like dif/2 and CLP(FD) to make your programs usable in all directions, increasing generality and ease of understanding.
See logical-purity, prolog-dif and clpfd for more information.

How to represent uniqueness?

I am trying to write an agent for determining what card a player has, and I am struggling to represent that each card can only have been dealt to a single player.
So have I have something^ like this:
player(p1).
player(p2).
card(ace).
card(king).
card(queen).
card(jack).
but I am struggling on writing the rule for uniqueness. Borrowing something from logic class, I though about defining uniqueness as "if X has Y, then if something has Y, that something must be X".
has_card(P, C) :-
player(P),
card(C),
not(player(P2),
P2 =\= P,
has_card(P2, C)
).
but this fails because not/3 is not defined.
I tried rewriting it as:
has_card(P, C) :-
player(P),
card(C),
player(P2),
P2 =\= P,
not(has_card(P2,C)).
but then the query (which I expect to return false)
has_card(P, ace).
errors out with
ERROR: =\=/2: Arithmetic: `player1/0' is not a function
So, how can I represent uniqueness?
^ complicating --likely-- unnecessary details omitted
EDIT: in first attempt at has_card I have P2==P which should have been P2=\=P, fixed now
First off, as the error is telling you, you are using =\=, which is arithmetic inequality. For comparing on standard order of terms, you should use \==.
Then, the "not" as in "true when negated goal not true", you should probably use \+, like this:
\+ a == b
which is the same as
a \== b
The not/1 predicate is still available in most Prolog implementations but not recommended.
Fixing these two things will sort out the problem you are having at the moment.
But, as it is at the moment, your has_card/2 at no point maps a card to a player, really (it uses circular logic as far as I can see). Since you are not showing how exactly you know which cards belong to which player at any given moment, it is difficult to comment on that. Either way, some sort of term that you pass around would be probably better than changing the database with assert and retract.

Sicstus Prolog custom labeling by use of variable(Sel) and value(Enum)

Let's say I pass the following list of domain variables to the labeling predicate:
Z=[X1,Y1,X2,X3,Y2,X4,Y3.......Xn,Ym],
labeling(...., Z).
For variable(Sel):
Further more I want the labeling to maybe choose all the Y's first before continuing on the X's.
Or even more complicated:
Start on a X or on a Y and the continue to label a X if there are more unlabeled compared to Y and vise versa.
For value(Enum):
To even complicate it I maybe want to have different strategy to use depending on if it is a X of if it is a Y.
My first attempt has been to use attributed variable and add further information to each variable:
put_atts( X1, type_var(is_xvar)),
put_atts( X2, type_var(is_xvar)),
put_atts( Y1, type_var(is_yvar)),
.
.
And the inside variable(Sel) and value(Enum) I can search and select by use of this attribute.
But since a fd_var is already an attributed variable, this attempt does not work very well.
So my question is: Is use of attributed variables the right strategy to solve such a task? Is there an alternative way to do this?
This is only a simplified example. I would need about 10 different variable types, not just two as shown here.
There is absolutely no problem with additional attributes on domain variables. As long as you are relying on labeling/2 for variable selection, that is the most natural solution.
An alternative way is to write your own search procedure that does not rely on labeling/2.

Resources