Compare two atoms in Prolog - prolog

I have been learning prolog.. I'm using a editor named prol1.1.1 I need to write rule to compare 2 strings, when i give something like
rel(a1,b1).
rel(a2,b2).
rel(b2,c2).
associatedWith(X,Y,Z) :- rel(X,Y),rel(Y,Z).
?- associatedWith(X,Y,Z).
it works
but when i give
?- associatedWith(X,Y,Z),X=\=Z.
i get parser exception
Parser exception [Should be evaluable ''a2''[7:31]] line 7:31
what i got from websites is =\= is for numeric values, i wasn't able to get answer for comparing string values.. can anyone help me..
and i wasn't able to get gui for swi-prolog can u please help me with that too?
i need to use the call prolog from java program and the output has to be again processed in java, can anyone please help me..

You are trying to compare atoms, not strings. Anyways, you need \=
?- aaa = aaa.
true.
?- aaa \= aaa.
false.
?- aaa \= aab.
true.

Related

What do these predicates do in Prolog

I don't understand what exactly these following 4 predicates do:
predicate1([H1,H2|T1],X) :−
append([H1,H2|T1],[H2,H1|T1],X).
predicate2wrapper(In, Out) :-
predicate2([ ], In, Out).
predicate2(L, [ ], L).
predicate2(A,[H| T], Out) :-
predicate2([H,H|A],T, Out).
predicate3([X,X], [X,X|_]).
predicate3([X,X], [_,H|T]) :−
predicate3([X,X],[H|T]).
predicate4([ ], _) .
predicate4([H|T], L) :−
member(H,L),
predicate4(T,L).
I know that all these predicates take lists as their argument(s) and I also tried to run them but I always get a Syntax error: operator expected warning.
Could someone please help me understand what these predicates do and maybe also help me fix this error?
Did you copy this from a pdf or a word-document? The --signs in your :- are not minus signs - this is causing the error. Retype them to solve the issue and then you can analyze the predicates. How to know if chars looking the same are not the same? I would suggest using a diff tool (a program to compare files, as command line or with a gui (winmerge), even available online) or an ascii to hex converter like this.
Example queries which give you a hint what these predicates do:
?- predicate1([1,2,3],L).
?- append([1,2,3],[4,5],L).
?- predicate2wrapper([1,2,3],L).
?- predicate3([c,c],[a,a,b,b]).
?- predicate3([b,b],[a,a,b,b,c,c]).
?- predicate3([X,X],[a,a,c,b,b]).
?- predicate4([a,b],[a,c,b]).
?- predicate4([a,d],[a,c,b]).
?- member(a,[a,c,b]).
?- member(d,[a,c,b]).

setof with compound predicate

I am struggling with a question in an assignment with prolog.
So, I have the following fact database in prolog:
student(name(doe, [john]), 33332, ['CSI1120'] ).
student(name(doe, [jane]), 33336, ['CSI1120'] ).
evaluation('CSI1120', homework(1), ['Prolog', database ], 5).
mark('CSI1120', 33332, homework(1), 3.5 ).
mark('CSI1120', 33336, homework(1), 4.0 ).
My goal here is to create a predicate listAllMarks/3 such as
?- returnAllMarks('CSI1120',homework(1),L).
Returns:
L= [(33332, 3.5), (33336, 4.0)].
In order to resolve this problem, I was thinking of making use of the prolog setof/3, so I came with the following predicate.
returnAllMarks(C,H,L):- setof(L,mark(C,_,H,X),[L|X]).
This doesn't seems to work, the predicate always return false. I"m suspecting that this may be due to the fact I am using setof against a compound predicate, but I could be wrong (I'm still in the early stages of learning prolog).
Do you guys have an idea? I look at this problem from all angles, and I am stuck here.
Thank you.
You could write something like:
returnAllMarks(C,H,L):- setof( (X,Y), mark(C,X,H,Y), L).
Example:
?- returnAllMarks('CSI1120',homework(1),L).
L = [ (33332, 3.5), (33336, 4.0)].

turning off Redefined static procedure in prolog

anyone of you could tell me how to turn off "Redefined static procedure" warnings?
I red online documentation of swi-prolog and i found this predicate no_style_check(ultimate) that in principle should turn off these warnings, but when i execute this predicate
main:-
no_style_check(singleton),
no_style_check(discontiguous),
no_style_check(multiple),
require,
test_all.
i received this error
ERROR: Domain error: style_name' expected, foundmultiple'
Anyone knows an alternative way to do this or could tell me why i receive this error ?
Thanks in advance!
Prolog is a pretty loosey-goosey language, so by default it warns you when you do certain things that are not wrong per se, but tend to be a good indication that you've made a typo.
Now, suppose you write something like this:
myfoo(3, 3).
myfoo(N, M) :- M is N*4+1.
Then from the prompt you write this:
?- asserta(myfoo(7,9)).
ERROR: asserta/1: No permission to modify static procedure `myfoo/2'
ERROR: Defined at user://1:9
What's happening here is that you haven't told Prolog that it's OK for you to modify myfoo/2 so it is stopping you. The trick is to add a declaration:
:- dynamic myfoo/2.
myfoo(3, 3).
myfoo(N, M) :- M is N*4+1.
Now it will let you modify it just fine:
?- asserta(myfoo(7,9)).
true.
Now suppose you have three modules and they each advertise themselves by defining some predicate. For instance, you might have three files.
foo.pl
can_haz(foo).
bar.pl
can_haz(bar).
When you load them both you're going to get a warning:
?- [foo].
true.
?- [bar].
Warning: /home/fox/HOME/Projects/bar.pl:1:
Redefined static procedure can_haz/1
Previously defined at /home/fox/HOME/Projects/foo.pl:1
true.
And notice this:
?- can_haz(X).
X = bar.
The foo solution is gone.
The trick here is to tell Prolog that clauses of this predicate may be defined in different files. The trick is multifile:
foo.pl
:- multifile can_haz/1.
can_haz(foo).
bar.pl
:- multifile can_haz/1.
can_haz(bar).
In use:
?- [foo].
true.
?- [bar].
true.
?- can_haz(X).
X = foo ;
X = bar.
:- discontiguous does the same thing as multifile except in a single file; so you define clauses of the same predicate in different places in one file.
Again, singleton warnings are a completely different beast and I would absolutely not modify the warnings on them, they're too useful in debugging.

Prolog no operand Predicates

I am examining a Prolog example as a tutorial. In this example I have a predicate with Zero operand like this:
print_all_solutions :-
findall(_,print_solution,_).
how can I call print_all_solution in the console?
When I ask this in the Prolog console I get nothing:
?- print_all_solutions
no answer, also :
?- print_all_solutions.
no answer.
While i get correct answers to other questions like:
?- goal(state([],right,[a,b,c,d],12)).
true.
?- goal(state([],right,[a,b,c,d],19)).
false.
How should I ask a question about predicates with no operand ( /0 ), to see the solution in the console?
I guess your problem is that either init(State) or, more probably, solve(State,Solution,EndState) don't work.
You need to debug: enter these commands after you consulted the source file
?- leash(-all),trace.
?- print_solution.
and you'll get some clue from the Prolog engine
I simply typed this in the console:
findall(_,print_all_solutions,_).
and i get the answer.

swi-prolog user login and registration

I have user input/ login as following:
login:- write('username: '), read(User), nl, write('password: '), read(Pass).
and i have a database with usernames and passwords. I use find predicate to get all rows as a list like shown in the code:
find(R):-findall(Row, rs('SELECT name FROM patient where name=\'James\'', Row), R).
?- find(R).
R = [row('James'), row('James'), row('James'), row('James')].
Is there a way to use user input from read() and check if that user is in database?
I tried member(User, R) but it's not working properly.
I know prolog is not best language for this kind of stuff(login/registration). The reason why I'm doing this is that i'm working on helath care expert system in swi-prolog and i need login and reg for patients.
Is there a why this can be done? I'm new to prolog so im getting stuck on lots of stupid things.
Thanks!
.............
#gusbro I tried with member(row(User) as you told me:
check:-findall(Row, rs('SELECT name FROM patient where name=\'James\'', Row), R),
read(User), member(row(User), R);
write('wrong username!').
But i always get the same no matter what i write:
?- check.
|: Bla.
true ;
wrong username!
true.
?- check.
|: James.
true ;
wrong username!
true.
What you tried didn't work because you are trying to unify terms of the form row(Atom) with Atom.
It should work fine if you do member(row(User), R).
However, note that in your example it will succeed more than once because you have repeated "rows"...
You might want to consider using setof/3 instead of findall/3, as it will eliminate duplicates from the resulting list (and as a side effect if will fail if there are no matches of the template of setof)

Resources