Prolog: take a list of two elements, return true if and only if the first element is same as second - list

I'm a newbie prolog programmer, and for an assignment, I have to have a basic program that succeeds if and only if list X is a list of two elements, with the first as the same as the second.
From my view of prolog, programs seem to be pretty small, so I typed this in:
firstPair(x,x).
When I run it under swipl, I get this as output:
Syntax error: Operator expected
Is there something more that needs to be done? I thought that if I executed this with say, firstPair(1,2). this would be all it would need to know that it is false.

First, lowercase x is not a variable, it's an atom. Make x uppercase to fix the problem:
firstPair(X,X).
Second, you do not type this into the interpreter. Rather, you write it into a file firstPair.pl, and then read that file into Prolog.
At the command prompt, type this:
['firstPair.pl'].
Press enter. Now you can use your firstPair/2 rule.
Finally, since the assignment talks about lists, I think the instructor wanted you to write firstPair/1, not firstPair/2:
firstPair([X,X]).

Your program/fact
firstPair(X,X).
will succeed if the two arguments given it can be unified, whether they are lists, atoms, variables, etc. To meet your specification, a
program that succeeds if and only if list X is a list of two elements,
with the first as the same as the second.
You need something like this:
list_of_two_elements( [X,X] ).
This will succeed if passed a single term that is (or can be unified with) a list of two elements that are, or can be made through unification, identical. For instance, all of the following will succeed:
list_of_two_elements( X ).
on success, the variable X will be unified with a list of two elements containing the same unbound variable, something like [V1,V1].
list_of_two_elements( [1,1] ).
list_of-two_elements( [1,X] ). (on success, X here will have been unified with the integer 1.)

Related

Assign variable in list

I've got a problem with Prolog lists.
Let's say I've got this predicate:
array(p, [A,B,C]).
When I do:
array(p,X).
I got: X = [_,_,_]
Now, considering I've got this predicate:
p1(1) :- array(p1, [1,B1,C1]).
I expected to get:
X = [1,_,_]
but instead, the result is the same as before. Is such a thing even possible in Prolog? Another question is if somehow we can set these values, could we overwrite these values in the same way? I understand that in the prolog variables are assigned only once but I would like to somehow get a dynamic list.
I'm not sure what you mean by "paradigm," and I'm very unclear on what you're trying to do with this code. If you have this at the toplevel:
array(p, [A,B,C]).
you are defining a fact array/2, which associates p with a list of three uninstantiated variables. Your first query amounts to retrieving this fact.
Your second "paradigm" is really the definition of a rule or predicate p1/1, which takes a single argument, which must be 1 for the rule to fire. The body of this second predicate is a call to the predicate array/2 which is definitely going to fail. I don't see how you could possibly get the same result as before, because you defined array(p, ...) before and now you are looking for array(p1, ...). Furthermore, there is no X in your second query, so there is no reason for X to appear in the result, and it definitely would not, even if you had called array(p, ...) instead of array(p1, ...).
I think what you're trying to do here is probably set up some kind of set of three variables and then unify each of them in turn as you proceed along some calculation. To do something like that is possible and easy in Prolog, but the fact database is not going to participate in this process really. You're going to have to write predicates that pass your variables along to other predicates that will unify them and return them bound. None of this is very hard, but it looks like you're going to have to go back and understand the fundamentals here a little better. You're far enough off track here that I don't think anyone can really answer your question as stated, because there's too much confusion in it.

searching in list getting true infinitely in prolog

I tried to code a Prolog program that takes 2 value and calculates if the pair is valid or not. If pairs are in different lists, then pairs will be valid and they can make match. If two team in same list(group) then they can't make match which means false.
when i started the program it doesn't show anything. I thought there would be infinite searching or looping. Then tried that simple code
GroupB=[china,usa,chile,italy].
member(X,[X|_]).
member(X,[_|T]):-
member(X,T).
match(X):-
member(X,GroupB).
In that code i saw that program always gives me true. I typed; to SWI-Prolog it gave me another true, i typed ; again another true then i realized that the problem should be in that searching part. Thanks for all interests from now. All suggestions are welcome.
edit:
I edited the code like that to try a different style
GroupA([germany,brazil,turkey,korea]).
GroupB([china,usa,chile,italy]).
member(X,[X|_]).
member(X,[_|T]):-
member(X,T).
memberence(X):-
GroupA(L).
GroupB(M).
member(X,L).
member(X,M).
collision(X,Y):-
GroupA(L),
member(X,L),
member(Y,L).
GroupB(L),
member(X,L),
member(Y,L).
match(X,Y) :-
GroupA(L),
memberence(X),
memberence(Y),
\+collision(X,Y).
now i got:
ERROR: Undefined procedure: match/2
ERROR: However, there are definitions for:
ERROR: catch/3
although there is a match(X,Y) procedure why it gives me undefined match/2 error.
GroupA=[germany,brazil,turkey,korea].
GroupB=[china,usa,chile,italy].
member(X,[X|_]).
member(X,[_|T]):-
member(X,T).
memberence(X):-
member(X,GroupA).
member(X,GroupB).
collision(X,Y):-
member(X,GroupA),
member(Y,GroupA).
member(X,GroupB),
member(Y,GroupB).
match(X,Y) :-
memberence(X),
memberence(Y),
\+collision(X,Y).
a)
You have a dot that must be comma in:
collision(X,Y):-
member(X,GroupA),member(Y,GroupA).
member(X,GroupB),member(Y,GroupB).
b)
Better you do not redefine "member", it is standard.
c)
If I change dot by comma in:
collision(X,Y):-
GroupA(L),member(X,L),member(Y,L),
GroupB(L),member(X,L),member(Y,L).
this statement will fail always because there are no list "L" common to GroupA and GroupB.
d)
If we take what seems the original request "takes 2 value and calculates if the pair is valid or not. If pairs are in different lists, then pairs will be valid and they can make match. If two team in same list(group) then they can't make match which means false."
the solution seems obvious:
match(X,Y) :- groupA(A), member(X,A), groupB(B), member(Y,B).
match(Y,X) :- groupA(A), member(X,A), groupB(B), member(Y,B).
You have 2 big problems.
First, you seem to use . and , interchangeably.
Second, you fail to understand Prolog's scoping rules. Anything that isn't asserted into the prolog database is scoped to the immediate statement or the clause of the predicate of which is a part. If you want somebody to know about it, it either has to be a part of the prolog database or passed as an argument. Thus, when you say something like
GroupB = [china,usa,chile,italy].
The variable GroupB Is unified with the list [china,usa,chile,italy]. At which point, the assertion succeeds, and both the newly-bound variable and the list with which it was unified ** go out of scope** and cease to exist. Then, when you attempt to reference it later on:
GroupB=[china,usa,chile,italy].
.
.
.
match(X) :- member(X,GroupB).
The variable GroupB is unbound. Your implementation of member/2,
GroupB=[china,usa,chile,
member(X,[X|_]) .
member(X,[_|T]) :- member(X,T) .
is more than willing to act in a generative manner when given an unbound variable as its 2nd argument, generating lists of variable, successively (and infinitely) longer on backtracking.

Prolog computing type of tuples

For an assignment, I have to create a type inference relation. here's the approach I used
tuples([]).
tuples(_|_).
type(tuples([]),tuples([])).
type(tuples(X|T),tuples(Y|Z)) :- type(tuples(T),tuples(Z)),type(X,Y).
I have already defined the type relation for all possible terms required for my assignment where y is the type of X in type(X,Y). For defining types of n-tuples, I used the approach similiar to the one used for appending lists.
But prolog always returns false when I ask
?-type(tuples([3,str]),Z)
or even
?-type(tuples([3,str]),tuples(Z))
or
?-type(tuples([3,str,4,abc,5,6]),Z)
i.e a list of length n, the answer returned is false.
Nothing changed even when I revered the sub-rules in the last rule.
tuples([]).
tuples(_|_).
type(tuples([]),tuples([])).
type(tuples(X|T),tuples(Y|Z)) :- type(X,Y),type(tuples(T),tuples(Z)).
I am not asking for alternative approaches to type of tuples to help me in my assignment but I can't figure out why this approach is not working.
It looks like your definition of a tuple is a List with length 2.
This rule does not check for that:
tuples(_|_).
What you probably want is this:
tuples([_,_]).
If you want it to check for any length list, use:
tuples([_|_]).
In the latter rule, the first wildcard represents the first item in the list (the head) and the second wildcard represents the rest of the list (the tail).

Silly detail enquiry about Prolog unification

In Prolog:
?-P=[A|B], P=[1,_].
P = [1, _G1091],
A = 1,
B = [_G1091]
B is shown as [_G1091] showing it's an uninstantiated variable. However, if I change a tiny bit...
?-P=[A|B], P=[1|_].
P = [1,B],
A = 1,
All of a sudden it's not interested in showing me that B is uninstantiated but still a variable ready to unify with anything.. how come? (I like to focus on weird details sometimes :) )
The precise details of Prolog syntax are sometimes quite subtle. To get used to it use write_canonical/1 which shows you the term in functional notation:
?- write_canonical([A|B]).
'.'(_1,_2)
true.
?- write_canonical([1,_]).
'.'(1,'.'(_1,[]))
true.
May I recommend a "drill"-exercise to get used to Prolog's list notation:
Take some list like [[1,2],3] and now try to write it down in as many variants you can imagine.
?- [[1,2],3] == [[1,2],3|[]].
true.
etc.
In many Prologs the toplevel lets you take the last input (often: cursor-up) such that you can re-edit the right-hand side rapidly.
In the first case:
?-P=[A|B], P=[1,_].
you are stating that P is a list with two elements, the first one being the number 1 (unified to variable A). Therefore, B has to be a list with one element (an unnamed variable).
On the other hand, in the second case:
?-P=[A|B], P=[1|_].
you are stating that P is a list with at least one element (1 again unified to A) but you are not stating anything else. B can be either an empty list, or a list with any amount of elements.
If you look at the second part of each query, the first amounts to
P=.(1,.(_,[]))
while the second amounts to
P=.(1,_)
In the first, B is bound to .(_,[]); that is, a list that contains an uninstantiated variable
In the second, B is bound to an uninstantiated variable
When a variable is just bound to an uninstantiated variable, there's no point in showing it; in the first example it's bound to something with some additional structure, so there is a point in showing it.

simple yes/no haskell list question

So I'm reading http://learnyouahaskell.com/starting-out as it explains lists, and using ghci on Vista 64. It says that [2,4..20] steps by 2 from 4 to 20. This works. It says [20,19..1] goes from 20 to 1, but doesn't explain. I take it that the first number is NOT the step, the step is the difference between the 1st and 2nd number. This is confirmed by [4,4..20] which hangs (no error message, must kill console). This is unlike operators like !! and take which check the index's range and give an error message.
My question is: is this a bug on Vista port or is that the way it's supposed to be?
[x,y..z] does indeed step from x to z by step y-x. When y-x is 0 this leads to an infinite list. This is intended behavior.
Note that if you use the list in an expression like take 20 [2,2..20], ghci won't try to print the whole list (which is impossible with infinite lists of course) and it won't "hang".
Quoting this book:
[n,p..m] is the list of numbers from n to m in steps of p-n.
Your list [4,4..20] "hangs", because you have a step of 4-4=0, so it's an infinite list containing only the number 4 ([4, 4, 4, 4...]).
Haskell allows infinite lists and as the Haskell is the "lazy evaluation language", meaning it will only compute what is necessary to give you the result, so the infinite structures are allowed in Haskell.
In Haskell you could compute something like "head[1..]". This is because Haskell only calculates what is required for the result. So in the example above it would generate only the first element of the infinite list (number 1) and head would return you this element (number 1).
So, in that case program will terminate! However, if you calculate [1..] (infinite list) program won't terminate. Same applies to your example, you created an infinite list and there is no way of terminating it.
That syntax basically is derived from listing the whole list. [1,3,5,7,9,11,13,15,17,19] for example can be shortened by simply omitting the obvious parts. So you could say, if I specify the first two elements, it is clear how it would continue. So the above list equals to [1,3..19].
It's worth noting that the .. syntax in lists desugars to the enumFrom functions given by the Enum typeclass:
http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#t:Enum