Using member in swi prolog - prolog

I am totaly new to prolog and have just started. I am currently learning about the build in function 'member' that seems simple; however, it returns the opposite of what I would expect it to do.
I tried printing the output of a very simple query:
member(6, [2,4,3,5]).
My expectation was that the output of this would be False
However, it returns True
I played with this further trying:
member(2, [2,4,3,5]).
Which returns False!?
Could someone explain if this is a mistake by me or that this is normal for prolog to do?

Related

Prolog list length comparison return true/false

I am trying to write a function longer(S1,S2) which should be true if S1 is longer than S2, otherwise false. What I have so far is the following:
longer(A,nil).
longer(nil,B) :- false.
longer([A,AS],[B,BS]) :- longer(AS,BS).
But for some reason I cannot seem to get it to parse correctly when I provide for instance the input: longer([1,2],[1]).
But when I run the above through swi-prolog it return false.
Another example is running the: longer([1],nil) which also return false, even though it should be true by matching with list(cons(A,As)) where As = nil, finally matching the end clause.
What am I missing? Can someone point me in the right direction here, as I cannot see how this is not evaluating to true.
Edit: it should be noted that I am still fairly new to prolog at this point.
Update I have had some misunderstanding in relation to what is common prolog semantic. Including trying to force the program to yield a false value (probably being steered by my understanding of non-declarative language semantics). I have updated my answer with the inputs from #tiffi.
That is a solution that is pretty close to the thinking behind what you have come up with:
longer([_|_],[]).
longer([_|As], [_|Bs]):- longer(As,Bs).
Your idea with regard to the first clause (before your edit) could be expressed like this:
longer(A,[]):- is_list(A). %is_list/1 is inbuilt
However, that doesn't give you the right result, since the empty list is also a list. Thus you need to make sure that the first argument is a non-empty list.

Predicate should concatenate and reverse, but always returns false

I am new at Prolog and just started practising the built-in list predicates. So I was trying to write a code that concatenates two lists and order them descending(reverse them). The problem is that the code always returns false, and I have no idea why it doesn't return what I am expecting.
reverse(append([6,5,4],[3,2,1]),Y).
Also tried:
reverse(append([6,5,4],[3,2,1],X),Y). & reverse(append([6,5,4],[3,2,1],X),X).
But none of them actually worked. I would be thankful if someone can tell me the solution.

Visual Prolog error c502: The expression does not produce a value

I am trying to translate a simple Turbo Prolog problem to Visual Prolog 7.1
The original Turbo Prolog code is the following.
DOMAINS
s=string sl=s* sll=sl*
PREDICATES
select(sl,s,sl)
solve(sll)
CLAUSES
select([A|B],A,B).
select([A|B],C,[A|D]):- select(B,C,D).
solve([["Anna",A,A],["Kate",Vp,Vt], ["Natasha",Np,"green"]]):-
select(["white","green","blue"],A,ColPl),
select(["white","blue"],A,[Vt]), Vt<>"white",
select(ColPl,Vp,[Np]), Vp<>"white", Np<>"green".
And its resulting list is outputted with solve(Out) with provides a correct result to the Turbo Prolog console.
When trying to translate this to Visual Prolog, I get error c502 in line 33.
implement main
open core
constants
className = "main".
classVersion = "".
domains
s=string.
sl=s*.
sll=sl*.
%
class predicates
select:(sl,s,sl) nondeterm anyflow.
solve:(sll) nondeterm anyflow.
%
clauses
%
select([A|B],A,B).
select([A|B],C,[A|D]):- select(B,C,D).
%
solve([["Anna",A,A],["Kate",Vp,Vt],["Natasha",Np,"green"]]):-
select(["white","green","blue"],A,ColPl),
select(["white","blue"],A,[Vt]), Vt<>"white",
select(ColPl,Vp,[Np]), Vp<>"white", Np<>"green".
clauses
classInfo(className, classVersion).
clauses
run():-
console::init(),
%ERROR AFTER THIS LINE
stdIO::writef("%", solve(Out)),fail().
end implement main
goal
mainExe::run(main::run).
What I get from this error is that solve(Out) does not give anything to print. What I do not know is how to change the code to produce something to print.
I am a beginner in Prolog and I cannot figure out how to fix this problem and Google is not much of a help either, this seems to be very obscure problem.
Thank you!
I'm not familiar with Visual Prolog, but could you rewrite the offending line as:
solve(Out), stdIO::writef("%", Out),fail().
and try again?
Remember that predicates are not functions like in other programming languages; they do not have a return value.
EDIT to answer comment: a procedure predicate should succeed exactly one time. Here, main is calling your solve function which my fail or succeeds several time. To ensure that, you can try to wrap the call to solve into another predicate:
wrap_solve(S) :- solve(S), !.
wrap_solve([]).
The cut after the call to solve should ensure that you get only one solution if it succeeds.
If there's no solution (i.e., the call to solve fails), then the second clause will give a default value (an empty list in that case).
In main, you should call wrap_solve instead of solve.

Why am I not getting a match?

I have a list structure called "stack".
At the point in my program which is causing problems, this is what stack holds:
stack([[s]],[np,[noun,john]])
I got this from running a trace, and its what stack is supposed to be holding.
When writing the next rule which is supposed to match this.
if
buffer([[Word|_]])
and aux(Word)
and stack([s],[np,[noun, john]])
If I do this then the rule executes as its supposed to. But I need to use a variable here instead of using "and stack([[s]],[np,[noun,john]])". However when I try to use anything else, the rule does not fire. I can't work out why. Other rules work fine when I use variables in the list.
Ive tried
stack([s]|Foo)
stack([s]|[Foo])
stack([MyHead]|[MyTail]... and literally every other combination I can think of.
I'm not entirely sure what is causing this problem
Your stack seems to have arity 2, where each arg is a list.
These aren't valid syntax for lists
stack([s]|Foo)
stack([s]|[Foo])
...
but since some Prolog declare the (|)/2 operator as alternative to (;)/2 (i.e. disjunction), you will not see any syntax error.
To understand you problem, you could try to unify, by mean of unification operator (=)/2
?- stack(S, Foo) = stack([[s]],[np,[noun,john]]).
you will get
S = [[s]]
Foo = [np,[noun,john]]

Undefined Procedure in SWI-Prolog does not work

I am just starting to use Prolog, and already I've run into problem with a seemingly simple example. Here is my .pl file:
hacker(P) :- mountaindew(P), doesntsleep(P).
hacker(P) :- writesgoodcode(P).
writesgoodcode(jeff).
Then, after I load the program into swipl, I test it with this line at the prompt
writesgoodcode(jeff).
I thought it would display true, but I get this error:
?- hacker(jeff).
ERROR: hacker/1: Undefined procedure: mountaindew/1
Exception: (7) hacker(jeff) ?
This program works fine, but this doesn't solve my problems:
hacker(P) :- writesgoodcode(P).
writesgoodcode(jeff).
$ swipl -s dumb.pl
% dumb.pl compiled 0.00 sec, 1,112 bytes
?- hacker(jeff).
true.
Can anyone explain why my original program doesn't work? From my understanding, Prolog should "skip" the first statement since it doesn't have enough information, and check the next line. It does have enough info for that second line, and thus it should evaluate true. Any help or a point in the right direction would be great. Thanks.
As the error message says, you have an undefined procedure mountaindew/1. To make your code return true, your options are:
Define this predicate
Declare that this predicate is dynamic: dynamic(mountaindew/1)
Declare that all unknown predicates should fail (not recommended): set_prolog_flag(unknown, fail)
you could also change the order of the predicates (cannot be done always ofc)
but mostly what Kaarel said.
in the end there is not really a point in writing something that will always fail, even if you are still developing the code
This works but as I am a beginner I can't say why. The word "uninstantiated" may apply. Despite not knowing why it works, I think it's helpful to show one way that works.
hacker(P) :- mountaindew(P), doesntsleep(P).
hacker(P) :- writesgoodcode(P).
mountaindew(john).
doesntsleep(john).
writesgoodcode(jeff).

Resources