Make function check objects in predicate Prolog - prolog

I've recently started learning Prolog and I've a question about predicates and functions. How can I write a function which will check if objects in a predicate is in another predicate For instance:
vertex(a).
edge(l,k,-1).
edge(k,l,4).
edge(a,z,-2).
checkEdges(edge(X,Y,_)) :- vertex(X),vertex(Y)
P.S How can I make this function to print a message if elements are not vertices?

Something like
checkEdges(edge(X,Y,_)) :-
( vertex(X), vertex(Y) ->
true
; write('not vertices'),nl ).
?

Related

Prolog: Assign value to Variable in Predicate

With the following rules:
test('John', ebola).
test('John', covid).
test('Maria', covid).
How can I create a predicate that would tell me if John or Maria took (both) the Ebola and Covid tests?
I want to do something similar to this (I know it's wrong, just the idea):
tests(Persona, Ebola, Covid) :-
Ebola = test(Persona, ebola),
Covid = test(Persona, covid).
Prolog is relational not functional. test(X, Y) either holds or fails and doesn't return a value like what you thought. Here's what you should have written:
tests(Persona) :-
test(Persona, ebola),
test(Persona, covid).
You can query tests('John') which is true since both test/2 calls succeeds. The query tests('Maria') fails because test('Maria', ebola) fails.
Does it answer your question ?

Define member function using concatenating

How to define member (X,L) using concatenating relationship? could anyone explain the method?
concatenate([],L,L).
concatenate([X|L],L2,[X|CL]):-concatenate(L,L2,CL).
It is given concatenating goals
Try the behaviour of concatenate/3 in your Prolog interpreter (the command line, AKA REPL) for this specific query:
?- L=[1,2,3], concatenate(_,[X|_],L).
This pattern it's actually what you need... but the details of adding a predicate member/2 will depend on the actual Prolog implementation.
I'd call it member/2 predicate, not a member function,
it sounds like the C++ term.
Here's concat_member/2:
concat_member( X, Xs ) :- concat( _ , [ X | _ ], Xs ).

Learn Prolog now: Why answering true to the first query of exercise 1.5?

I have just started learning Prolog, and I'm wondering about the first question of this exercise.
%% Suppose we are working with the following knowledge base:
wizard(ron).
hasWand(harry).
quidditchPlayer(harry).
wizard(X) :- hasBroom(X), hasWand(X).
hasBroom(X) :- quidditchPlayer(X).
How does Prolog respond to the following queries?
wizard(ron). -> true
witch(ron). -> undefined procedure
wizard(hermione). -> false
witch(hermione). -> undefined procedure
wizard(harry). -> true
wizard(Y). -> Y = ron ; Y = harry.
witch(Y). -> undefined procedure
Using swipl on Ubuntu, importing the knowledge base for this exercise, first of course trying to decipher what Prolog will returns, and finally checking by myself.
Ok pretty boring stuff until now, I have seen a few answer to these exercises over Github (here, here and there), and I don't understand the answer to the first one: %% 1. wizard(ron). -> true.
First of all the interpreter is complaining about the two definition of what is a wizard:
Warning: /tmp/prolog/ex15.pl:4:
Clauses of wizard/1 are not together in the source-file
Earlier definition at /tmp/prolog/ex15.pl:1
Current predicate: quidditchPlayer/1
Use :- discontiguous wizard/1. to suppress this message
Secondly, when querying I obtain:
?- wizard(ron).
true ;
false.
The way I get it, first Prolog returns the first fact from the knowledge base, then apply the rule head and find out that ron has neither a broom nor a wand.
All this leading to my question: what subtlety have I missed that makes others writing true as an answer to this query?
what subtlety have I missed that makes others writing true as an answer to this query?
`?- wizard(ron).`
true;
false
You have the clause (fact) wizard(ron). in your KB.
To make the things clearer you can write the fact also as the rule clause:
wizard(ron) :- true.
As you can see this is pretty redundant notation but useful in some cases as the general fact representation.
So your query can be interpreted as follows:
Is there an wizard called ron?
Since you have the fact wizard(ron) :- true.
Prolog will first unify the goal and the head.
In your case unify is trivial comparison because no variables are in the goal and the head.
Then Prolog tries to prove body. The body is builtin predicate true, so you quickly get the answer - true.
Then pressing ';' you initiate the search for the alternative solution.
Since no (more) solutions exist for the query wizard(ron), Prolog writes false.
The dot operator designates the clause end. So you wrongly typed dots in your examples:
-> operator means if-then-else relation. It can be used within clause body.
For example you can write std_member/2 as if_member/2
std_member(X, [ X | _ ]).
std_member(X, [ _ | Xs ]) :-
std_member(X, [ _ | Xs).
if_member(X, [ Y | Xs ]) :-
X = Y -> true;
if_member( X, Xs ).

Using "=" in Prolog

I'd like to know why I get an error with my SWI Prolog when I try to do this:
(signal(X) = signal(Y)) :- (terminal(X), terminal(Y), connected(X,Y)).
terminal(X) :- ((signal(X) = 1);(signal(X) = 0)).
I get the following error
Error: trabalho.pro:13: No permission to modify static procedure
'(=)/2'
It doesn't recognize the "=" in the first line, but the second one "compiles". I guess it only accepts the "=" after the :- ? Why?
Will I need to create a predicate like: "equal(x,y) :- (x = y)" for this?
Diedre - there are no 'functions' in Prolog. There are predicates. The usual pattern
goes
name(list of args to be unified) :- body of predicate .
Usually you'd want the thing on the left side of the :- operator to be a predicate
name. when you write
(signal(X) = signal(Y))
= is an operator, so you get
'='(signal(X), signal(Y))
But (we assume, it's not clear what you're doing here) that you don't really want to change equals.
Since '=' is already in the standard library, you can't redefine it (and wouldn't want to)
What you probably want is
equal_signal(X, Y) :- ... bunch of stuff... .
or
equal_signal(signal(X), signal(Y)) :- ... bunch of stuff ... .
This seems like a conceptual error problem. You need to have a conversation with somebody who understands it. I might humbly suggest you pop onto ##prolog on freenode.net or
some similar forum and get somebody to explain it.
Because = is a predefined predicate. What you actually write is (the grounding of terms using the Martelli-Montanari algorithm):
=(signal(X),signal(Y)) :- Foo.
You use predicates like functions in Prolog.
You can define something like:
terminal(X) :- signal(X,1);signal(X,0).
where signal/2 is a predicate that contains a key/value pair.
And:
equal_signal(X,Y) :- terminal(X),terminal(Y),connected(X,Y).

Prolog error in loop

I would need help about Prolog.
I posted my code, the problem is that i do not obtain the expected result.
I want planning actions for moving on table all blocks until is possible. To do this I prompt :
?- do(while(some(x, block(x) & -onTable(x)),pi(x,putOnTable(x))),s0,S).
I expect to see a response like :
S = do(putOnTable(e), do(putOnTable(b), do(putOnTable(c), s0)))
but Prolog returns "false" only. Someone can help me??
% Golog interpreter
%:- [golog_swi].
:- discontiguous clear/2, on/3, onTable/2.
:- op(800,xfy,[&]).
do(E,S,do(E,S)):- primitive_action(E),poss(a,S).
% Primitive Action Declarations.
primitive_action(putOn(_,_)).
primitive_action(putOnTable(_)).
poss(putOn(X,Y),S) :- clear(X,S), clear(Y,S), \+ on(X,Y,S), \+ X=Y.
poss(putOnTable(X),S):- clear(X,S), \+(onTable(X,S)).
% Successor State Axioms.
on(X,Y,do(A,S)):- A = putOn(X,Y); on(X,Y,S), \+ (A = putOnTable(X); A = putOn(X,_)).
onTable(X,do(A,S)) :- A = putOnTable(X); onTable(X,S), \+ A= putOn(X,_).
clear(X,do(A,S)) :- on(Y,X,S), (A = putOn(Y,_) ; A = putOnTable(Y)); clear(X,S), \+ A = putOn(_,X).
% Restore suppressed situation arguments
restoreSitArg(onTable(X),S,onTable(X,S)).
restoreSitArg(on(X,Y),S,on(X,Y,S)).
restoreSitArg(clear(X),S,clear(X,S)).
block(X):- member(X,[a,b,c,d,e]).
% iniTial COndition
onTable(a,s0).
on(b,a,s0).
on(c,b,s0).
clear(c,s0).
onTable(d,s0).
on(e,d,s0).
clear(3,s0).
thank you!!!
Your predicate do/3 cannot succeed because the goal primitive_action/1 will fail with your query.
Currently, while/2 is not described in primitive_action/1 and it seems it is missing also from your program. So you need to extend primitive_action/1 by further facts, or add a new rule to do/3. And in addition to that you need to describe what while/2 means.
This question is actually about Golog. Your mistake is pretty mundane: you didn't copy the Golog interpreter code into your source file/directory.
Golog defines a number of high-level programming constructs, including while-loops and non-deterministic picks (pi), used here. I'm sure you don't want to reinvent Golog, so just go and get it. I'm assuming that your question is part of an assignment of sorts, and your teacher probably pointed you to the Golog interpreter. Otherwise, you can always find it on the pages of the cognitive robotics group at the Univ. of Toronto: http://www.cs.toronto.edu/cogrobo/main/systems/index.html

Resources