Consider the following:
link(step1, step2) .
link(step2, step3) .
link(step3, step4) .
goal(X) :- \+ link(X, _) .
I would like goal functor to represent a step that is not at the beginning of a link.
But when I try :
| ?- goal(X).
no
(instead of telling me that step4 is a solution)
The following, however, does evaluate to yes:
goal(step4).
I'm guessing that's because I'm asking prolog to find what it can't find (sigh…)
Any way I can do this?
The trouble comes with Prolog not knowing what your universe of valid values of X could be. In this particular example, you could do it by defining what a valid step is:
valid_step(X) :- link(X, _) ; link(_, X).
This would then help you tell goal what to choose from for the "universe of valid steps":
goal(X) :- valid_step(X), \+ link(X, _).
Yielding:
| ?- goal(X).
X = step4
yes
| ?-
Or, if more specifically, you really mean to find X which is present as a destination link but not a source link:
goal(X) :- link(_, X), \+ link(X, _).
It depends upon the big picture of what your facts are, what they mean, and what the semantics of goal really are.
Perhaps a more suitable way to define valid steps, if the link relation isn't what logically definesto what a valid step is, would be to make valid_step a set of facts, instead of the predicate I show above:
valid_step(step1).
valid_step(step2).
valid_step(step3).
valid_step(step4).
valid_step(step5).
So this is a simple, completely independent definition of what a valid step is, and can be used by other relations (predicates) that need this information.
It may be tempting to do:
valid_steps([step1,step2,step3,step4,step5]).
And then:
goal(X) :- valid_steps(Valid), member(X, Valid), \+ link(X, _).
But I believe the list of discrete facts is preferable.
Related
If for example, I have a Prolog predicate like
a(A, B).
Is it possible to collect, given a value of A, is it possible to collect all values of B that succeeds the predicate a, into a list, without using built in predicates such as bagof/3 or findall/3.
You have two obvious options (obvious to me; it seems there is more). One is to indeed use the database to save the state. This has at least one pitfall: depending on the name you decide to use for the temporary state, you might destroy some other state your program is keeping. This is the same old "global state"/"global variable" problem that all languages suffer from.
The other option would be to use a "local variable" and non-backtracking assignment to it to keep the temporary state. This is most probably going to be implementation dependent. For starters, you can look at nb_setarg/3 for SWI-Prolog.
However, both solutions are silly, given that you have findall, bagof, setof. You must motivate the need for something else to replace those. Just saying "is it possible" is not good enough since it is possible, but completely unnecessary, unless you know something else that you aren't telling us.
Here's a sketch of a stupid setof that uses other builtins, though not assert, and not exactly the ones listed by #false in a comment.
We'll use a list accumulator to collect solutions:
stupid_setof(Template, Goal, Set) :-
stupid_setof(Template, Goal, [], Set).
There are two cases to consider: Either the Goal can enumerate a solution we have not seen so far, or the only ones it can enumerate are already in our accumulator.
First, the case where there are no solutions we haven't seen. In this case we're done.
stupid_setof(Template, Goal, SolutionsSeen, Set) :-
\+ ( call(Goal),
\+ member(Template, SolutionsSeen) ),
!,
sort(SolutionsSeen, Set).
Now for the stupid part. Consider:
foo(a).
foo(b).
foo(c).
?- SolutionsSeen = [], foo(X), \+ member(X, SolutionsSeen), !.
SolutionsSeen = [],
X = a.
?- SolutionsSeen = [a], foo(X), \+ member(X, SolutionsSeen), !.
SolutionsSeen = [a],
X = b.
?- SolutionsSeen = [a, b], foo(X), \+ member(X, SolutionsSeen), !.
SolutionsSeen = [a, b],
X = c.
?- SolutionsSeen = [a, b, c], foo(X), \+ member(X, SolutionsSeen), !.
false.
So given a list of solutions we've seen before, we can force Goal to backtrack until it gives us one that we haven't seen before. Note that these queries are independent: In each one we have a completely fresh copy of the foo(X) goal that starts enumerating from a.
We can do the same thing programmatically by copying the original goal before calling it, forcing it to start a fresh enumeration from a fresh instance of the Goal. If this finds a new solution, we can add it to our solutions, then repeat with another fresh copy of the goal, forcing it to enumerate yet another new solution, and so on:
stupid_setof(Template, Goal, SolutionsSeen, Set) :-
copy_term(Goal-Template, GoalInstance-Solution),
call(GoalInstance),
\+ member(Solution, SolutionsSeen),
!,
stupid_setof(Template, Goal, [Solution | SolutionsSeen], Set).
If Goal has N answers, this will enumerate on the order of N**2 of them and do corresponding linear searches in the solutions list. It will also perform any side effects that Goal has multiple times.
But it "works":
?- stupid_setof(X, foo(X), Xs).
Xs = [a, b, c].
And, despite all of its stupidity, this is still less stupid than the standard setof/3 if Goal has no solutions:
:- dynamic bar/1. % no clauses
?- setof(X, bar(X), Set).
false.
?- stupid_setof(X, bar(X), Set).
Set = [].
Lets suppose my db.pl file consists of only
male(Oliver)
male(james)
male(sam)
female(X) :- \+ male(X)
Now if I query,
?- male(X).
Then this will successfully return all the males.
But if I query,
?- female(X)
Then this will not. However, if I put a name in the female predicate, it correctly gives the output as yes/no.
What am I missing here? How do I get the list of all females? Or basically list of "not male".
I thought I'd give a proper answer as well. As mentioned in the comments, the fact male(Oliver). contains the variable Oliver such that e.g. also male(catherine_the_great) succeeds. But fixing this mistake will not solve the problem. Suppose we fix the facts for male and define female as above:
male(oliver)
male(james)
male(sam)
female(X) :-
\+ male(X).
Then we can not derive male(catherine_the_great) anymore but female(catherine_the_great) succeeds:
?- male(catherine_the_great).
false.
?- female(catherine_the_great).
true.
Unfortunately, by this definition, a hamburger is also female:
?- female(hamburger).
true.
What's even worse is, when we ask if there exists someone female (at all!), we get no as an answer:
?- female(X).
false.
The reason for this is that \+ is not classical negation(*) but what is called weak negation / negation as failure. \+ male(X) is true if there is no X such that male(X) is derivable. But as soon as male/1 succeeds with any solution (e.g. male(oliver)), the negation fails. In such cases the substitution male(X) is not proper substiution for female(X) but how are we supposed to get a list of all women? A possible solution is a list of persons of which we define male/female as subsets:
person(oliver).
person(james).
person(sam).
person(jackie).
person(selma).
male(oliver).
male(james).
male(sam).
female(X) :-
person(X),
\+ male(X).
When we query a list of all women, we now get:
?- female(X).
X = jackie ;
X = selma.
I'd rather use a separate predicate listing women though because it is less error prone when adding new persons.
In general, negation as failure is rarely safe. Two rules of thumb i have for myself:
whenever \+ p(X) appears as a goal, it is fully instantiated (a ground term). In our case, this is what person assures.
p(X) terminates for every ground term X. This assures termination of the negation as well.
(*) in classical logic, the rule of generalization female(jackie) → ∃X female(X) holds but here we can not derive ∃X female(X) despite being able to derive female(jackie).
The Cousin Explainer
Write a program that when given a person of reference and a degree the program can tell me all of the nth degree cousins that person has. I've started by writing my facts: male/1 female/1 and child/2 these are populated with the names of my family members. I then began writing rules for cousins I figured id write a different rule for every degree so only up to the third cousins. The problems I'm having are as follows.
firstCousin_of(X,Y):-child(X,Z1),child(Y,Z2),child(Z1,Z),child(Z2,Z). I have this to find a first cousin but the 2nd cousin is more complicated which makes me think there has gotta be a way to do this recursively.
I need the rule, all_cousins(Person, Degree, ListOfCousins), which after figuring out all of the nth degree cousins edits a list of all cousins to only include those specific nth degree cousins. I'm used to imperative languages and all i can think about with this is how do I even convey to the rule which people to remove from the list from one rule to another.
lastly I have a rule, all_cousinsRemoved(Person, Degree, removed(Number, Direction), ListOfCousins) that I don't even know where to start with but ill need the all_cousins rule for this one because it does the same thing but also only includes cousins in the edited lists w=that were removed nth times either up or down.
The best solutions is make a several rules that call other rules, here an example
male(dicky).
male(randy).
male(mike).
male(don).
male(elmer).
female(anne).
female(rosie).
female(esther).
female(mildred).
female(greatgramma).
male(blair).
male(god).
female(god).
parent(don,randy).
parent(don,mike).
parent(don,anne).
parent(rosie,randy).
parent(rosie,mike).
parent(rosie,anne).
parent(elmer,don).
parent(mildred,don).
parent(esther,rosie).
parent(esther,dicky).
parent(greatgramma,esther).
parent(randy,blair).
male(mel).
male(teo).
parent(melsr,mel).
parent(melsr,teo).
american(anne).
american(X) :- ancestor(X,anne).
american(X) :- ancestor(anne,X).
relation(X,Y) :- ancestor(A,X), ancestor(A,Y).
father(X,Y) :- male(X),parent(X,Y).
father(god, _) :- male(god).
mother(X,Y) :- female(X),parent(X,Y).
son(X,Y) :- male(X),parent(Y,X).
daughter(X,Y) :- female(X),parent(Y,X).
grandfather(X,Y) :- male(X),parent(X,Somebody),parent(Somebody,Y).
aunt(X,Y) :- female(X),sister(X,Mom),mother(Mom,Y).
aunt(X,Y) :- female(X),sister(X,Dad),father(Dad,Y).
sister(X,Y) :- female(X),parent(Par,X),parent(Par,Y), X \= Y.
uncle(X,Y) :- brother(X,Par),parent(Par,Y).
cousin(X,Y) :- uncle(Unc , X),father(Unc,Y).
ancestor(X,Y) :- parent(X,Y).
ancestor(X,Y) :- parent(X,Somebody),ancestor(Somebody,Y).
brother(X,Y) :- male(X),parent(Somebody,X),parent(Somebody,Y), X \= Y.
Retrived from this repository
Hi guys :) I have encountered problem during programming in prolog. I have partial order defined as facts, and I have defined maximal and greatest element as predicates. We can think of partial order like greater or equal, so le(6,7) is something like 6 <= 7.
le(6,7).
le(4,4).
le(6,6).
le(5,6).
le(5,5).
le(4,5).
le(4,4).
maximal(X) :-
not((le(X,Z) , X\=Z)).
greatest(X) :-
not(le(X,_)).
minimal(X) :-
not((le(Z,X) , X\=Z)).
smallest(X) :-
not(le(_,X)).
When I have typed query like maximal(7) the prolog output is true, and when I ask prolog to find the solution like maximal(X) it gives mi fail. I am beginner prolog programmer, so sorry if the question is too trivial, but I couldn't find the solution on my own.
Prologs uses pre-defined steps to find the answer and negation is always tricky.
To make a long story short, to make the code easier to reason about most logic should be positive and negation applied to expressions where values of all variables are known.
Here is how you could make the code work.
le(6,7).
le(4,4).
le(6,6).
le(5,6).
le(5,5).
le(4,5).
le(4,4).
is_my_number(X) :- le(X, _).
is_my_number(X) :- le(_, X).
equal_or_not_le(X, Y) :- X = Y.
equal_or_not_le(X, Y) :- not(le(X, Y)).
maximal(X) :- is_my_number(X), forall(is_my_number(Y), equal_or_not_le(X, Y)).
Then query:
?- maximal(X).
X = 7 .
Good luck!
I have two predicates:
foo(Y,X)
bar(Y,Z)
After running foo, How can I run bar with all possibilities of Y ?
example:
foo(Y, key) % all possibilities of Y => chat
% faq
% about
% search
How can I run bar with these all possibilities ?
bar(chat, Z)
bar(faq, Z)
bar(about, Z)
bar(serach, Z)
And then store all the results of Z in a list Zs?
foo/2 and bar/2 are already in join, and after each run of foo/2 bar/2 will be tried.
Maybe you are looking for forall(foo(Y,X), bar(Y,Z)), that run all possibilities of foo/2, and then bar/2. I.e. is required that bar/2 doesn't fail.
To understand the behaviour of forall/2, as well as other all solutions builtins, like setof/3, can be useful test with very simple builtins, with well known behaviour:
?- forall(member(X,[f,o,o]),(member(Y,[b,a,r]),writeln(X-Y))).
f-b
o-b
o-b
true.
You can see that the complete solution search of forall applies to its first argument, not the second.
HTH
allZs(X, Zs) :-
setof(Y, foo(Y, X), Ys),
maplist(bar, Ys, Zs).
related SWI-Prolog man pages: Finding all Solutions to a Goal and library apply
Note: usually in Prolog the convention is to put intput arguments before output ones - in your first predicate that'd mean foo(X, Y) instead of foo(Y, X). Plus here it'd outline the transitivity: foo(X, Y), bar(Y, Z)..
I think you want something like this:
barOnList([], []).
barOnList([Y|Ys], [Z|Zs]) :- bar(Y, Z), barOnList(Ys, Zs).