Prolog computing type of tuples - list

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).

Related

Prolog Insert the number in the list by the tail

How can I build a predicate in prolog that receives a number and a list, I must insert the number in the list by the tail
I tried inserting the number in the list by the head: insert(H,[P|Q],[H,P|Q]). and it works, but how can I do it by the tail?
Simply use append/3 like this:
?- append([a,b,c,d],[x],List).
List = [a,b,c,d,x].
Inserting at the tail can be done with a two-part recursive rule:
When the list is empty, unify the result to a single-element list with the item being inserted
When the list is not empty, unify the result to a head followed by the result of inserting into the tail of a tail.
English description is much longer than its Prolog equivalent:
ins_tail([], N, [N]).
ins_tail([H|T], N, [H|R]) :- ins_tail(T, N, R).
Demo.
Nobody talked about difference lists yet.
Difference lists
Difference lists are denoted L-E, which is just a convenient notation for a couple made of a list L whose last cons-cell has E for its tail:
L = [ V1, ..., Vn | E]
The empty difference list is E-E, with E a variable. You unify E whenever you want to refine the list.
For example, if you want to add an element X, you can unify as follows:
E = [X|F]
And then, L-F is the new list. Likewise, you can append lists in constant time. If you unify F with a "normal" list, in particular [], you close your open-ended list. During all operations, you retain a reference to the whole list through L. Of course, you can still add elements in front of L with the ususal [W1, ..., Wm |L]-E notation.
Whether or not you need difference lists is another question. They are intereseting if adding an element at the end is effectively a common operation for you and if you are manipulating large lists.
Definite clause grammars
DCG are a convenient way of writing grammar rules in Prolog. They are typically implemented as reader macros, translating --> forms into actual predicates. Since the purpose of grammars is to build structures during parsing (a.k.a. productions), the translation to actual predicates involves difference lists. So, even though both concepts are theoretically unrelated, difference lists are generally the building material for DCGs.
The example on wikipedia starts with:
sentence --> noun_phrase, verb_phrase.
... which gets translated as:
sentence(S1,S3) :- noun_phrase(S1,S2), verb_phrase(S2,S3).
A lot of "plumbing" is provided by the syntax (a little like monads). The object being "built" by sentence/2 is S1, which is built from different parts joined together by the predicates. S1 is passed down to noun_phrase, which builds/extends it as necessary and "returns" S2, which can be seen as "whatever extends S1". This value is passed to verb_phrase which updates it and gives S3, a.k.a. whatever extends S2. S3 is an argument of sentence, because it is also "whatever extends S1", given the rule we have. But, this is Prolog, so S1, S2 and S3 are not necessarly inputs or outputs, they are unified during the whole process, during which backtracking takes place too (you can parse ambiguous grammars). They are eventually unified with lists.
Difference lists come to play when we encounter lists on the right-hand side of the arrow:
det --> [the].
The above rule is translated as:
det([the|X], X).
That means that det/2 unifies its first argument with an open-ended list which tail is X; other rules will unify X. Generally, you find epsilon rules which are associated with [].
All the above is done with macros, and a typical error is to try to call an auxiliary predicate on your data, which fails because the transformation add two arguments (a call to helper(X) is in fact a call to helper(X,V,W)). You must enclose actual bodies between braces { ... } to avoid treating prediates as rules.
Here is an another option.
insert(N,[],[N]).
insert(N,[H|T],[H|Q]) :- conc([H|T],[N],[H|Q]).
conc([],L,L).
conc([H|T],L,[H|Q]) :- conc(T,L,Q).

Prolog create list of lists

I'm having some (or a lot of) trouble with lists of lists in prolog.
So I have a list of numbers, say [5,6,1,3] as input.
The output should be [[5,25],[6,36],[1,1],[3,9]].
I already have a predicate that 'return's the 2 item lists (keep in mind that I'll have to change the get_squared_pair function to get some other relevant value):
get_squared_pair(Number, Result) :-
get_squared_value(Number, SquareValue),
Result = [Number, SquareValue].
get_squared_value(Number, Result) :-
Result is Number * Number.
Until here it's pretty logical. Now I need a predicate that recursively iterates though a list, adds the squared pair to a new list, and then returns this lists of lists. What I have right now is:
return_list([], 0).
return_list([Head | Tail], Result) :-
get_squared_pair(Head, Add),
append(Add,Result),
return_list(Tail, Result).
This doesn't work for a number of reasons, and it's mostly because I can't seem to figure out how the recursion actually works with lists, much less lists of lists. Also it's currently running in the wrong order which doesn't help.
I understand this might be a bit vague but I've tried googling my way out of this one but can't seem to translate what I find into my own problem very well.
Any help would be much appreciated!
Let's look at your get_squared_pair/2 first. Although it's working, it can be tidied up a bit which will also help understand how Prolog works. The primary mechanism of Prolog is unification, which is not the same as assignment which occurs in other languages. In unification, Prolog examines two terms and attempts to unify them by instantiating variables in one or both of the terms to make them match. There are some predicates in Prolog, like is/2 which are used to evaluate expressions in one argument, and then unify the first argument with that result.
Your first predicate, then, which you have written as:
get_squared_pair(Number, Result) :-
get_squared_value(Number, SquareValue),
Result = [Number, SquareValue].
get_squared_value(Number, Result) :-
Result is Number * Number.
Can be simplified in two ways. First, you can consolidate the get_squared_value/2 since it's just one line and doesn't really need its own predicate. And we'll rename the predicate so it's not imperative.
square_pair(Number, Square) :-
S is Number * Number, % Square the number
Square = [Number, S]. % Unify Square with the pair
Prolog can unify terms in the head of the clause, so you can avoid the redundant unification. So this is all you need:
square_pair(Number, [Number, Square]) :-
Square is Number * Number.
On to the main predicate, return_list/2. First, we'll rename this predicate to square_pairs. When doing recursion with lists, the most common pattern is to continue reducing a list until it is empty, and then a base case handles the empty list. Your implementation does this, but the base case is a little confused since the 2nd argument is an integer rather than a list:
square_pairs([], 0).
This really should be:
square_pairs([], []).
Your main predicate clause isn't making correct use of append/2. There are two forms of append in SWI Prolog: append/2 and append/3. You can look up what these do in the SWI Prolog online documentation. I can tell you that, in Prolog, you cannot change the value of a variable within a predicate clause once it's been instantiated except through backtracking. For example, look at the following sequence that might be in a predicate clause:
X = a, % Unify X with the atom 'a'
X = b, % Unify X with the atom 'b'
In this case, the second expression will always fail because X is already unified and cannot be unified again. However, if I have this:
foo(X), % Call foo, which unifies X with a value that makes 'foo' succeed
bar(X, Y), % Call bar, which might fail based upon the value of 'X'
In the above case, if bar(X, Y) fails, then Prolog will backtrack to the foo(X) call and seek another value of X which makes foo(X) succeed. If it finds one, then it will call bar(X, Y) again with the new value of X, and so on.
So append(Add, Result) does not append Add to Result yielding a new value for Result. In fact, append with two arguments says that the second list argument is the concatenation of all the elements of the first list, assuming the first argument is a list of lists, so the definition of append/2 doesn't match anyway.
When thinking about your recursion, realize that the argument lists are in one-to-one correspondence with each other. The head of the result list is the "square pair" for the head of the list in the first argument. Then, recursively, the tail of the 2nd argument is a list of the square pairs for the tail of the first argument. You just need to express that in Prolog. We can also use the technique I described above for unification within the head of the clause.
square_pairs([Head | Tail], [SqPair | SqTail]) :-
square_pair(Head, SqPair),
square_pairs(Tail, SqTail).
square_pairs([], []).
Now there's another simplification we can do, which is eliminate the square_pair/2 auxiliary predicate completely:
square_pairs([Head | Tail], [[Head, SqHead] | SqTail]) :-
SqHead is Head * Head,
square_pairs(Tail, SqTail).
square_pairs([], []).
There's a handy predicate in Prolog called maplist which can be used for defining a relationship which runs parallel between two lists, which is the scenario we have here. We can bring back the square_pair/2 predicate and use maplist:
square_pairs(Numbers, SquarePairs) :-
maplist(square_pair, Numbers, SquarePairs).
So you want to turn your list into another, such that each element (a number) is turned into a two-element list, the number and its square.
All you need to do is to tell that to Prolog. First, the second one:
turn_into_two(Num, [A,B]):-
what is A?
A is Num,
what is B? We just tell it to Prolog, too:
B is ... * ... .
Now, on to our list. A list [A|B] in Prolog consists of its head element A, and its tail B - unless it's an empty list [] of course. It doesn't matter what the list's elements are; a list is a list.
We need to account for all cases, or else we're not talking about lists but something else:
turn_list([], Res):-
so what is our result in case the list was empty? It should be empty as well, right?
Res = ... .
in the other case,
turn_list([A|B], Res):-
our result won't be empty, so it'll have its head and tail, correct?
Res = [C|D],
next we say what we know about the heads: the input list's head turns into that two elements list we've described above, right?
turn_into_two(A,C),
and then we say our piece about the tails. But what do we know about the tails? We know that one is the result of the conversion of the other, just as the whole list is:
turn_list( ... , ...) .
And that's it. Incidentally, what we've described, follows the paradigm of mapping. We could have used any other predicate in place of turn_into_two/2, and it would get called for each of the elements of the input list together with the corresponding element from the resulting list.

Prolog not showing output in correct format

I am new to Prolog and I am trying to remove the last element from a list. The code I have tried:
removeLast([],[_]).
removeLast([_|T], [_|OT]):-removeLast(T, OT).
Obtained from here. I executed the code from SWi Prolog and I am getting a weird output ...
1 ?-
| removeLast(X, [1,2,3,4]).
X = [_G299, _G302, _G305] .
This is supposed to show [1,2,3], instead it is showing some numbers(?)
I don't know what am I doing wrong, why it is displaying in this format? I tried every Google combination I know of to search this term, although I saw people use this format directly in their queries like, parent(X, _G3248).
Update: Thanks to #lurker, modifying the code to the original format gives the output correctly:
removeLast([],[_]).
removeLast([X|T], [X|OT]):-removeLast(T, OT).
15 ?- removeLast(X, [1,2,3,4]).
X = [1, 2, 3]
But can someone explain, what is _G3240?
Here's the difference in the behavior of the solutions. Let's take the malfunctioning one.
removeLast([],[_]).
This rule says that if I have a list of one element, then the corresponding list with last element removed is [] and I don't care what that one element was (it could even be a variable). This is true, and a valid rule.
removeLast([_|T], [_|OT]) :- removeLast(T, OT).
This rule says that [_|T] is [_|OT] with the last element removed if I don't care what their first elements are and T is OT with its last element removed (following the same rules). This doesn't sound quite right. It means that if I am removing the last element from a list, I don't care what element I have in my result. So you get an arbitrary list of elements whose count is one less than your original list. But the elements don't match those at the front of the original list. In Prolog, the two _ instances are different anonymous variables. They are not unified.
The corrected clause is:
removeLast([X|T], [X|OT]) :- removeLast(T, OT).
This says that a list [X|T] is the list [X|OT] with its last element removed if T is the list OT with its last element removed. The common X means they share the same head of the list, which is correct. When the recursion reaches the very last element of the second argument, then the first clause is matched and that single-element tail is replaced by the empty list []. And then you get the correct, final result.
I refer to the _ variable as "anonymous" rather than "don't care" since there are some uses for anonymous variables in which their values do matter. Often though, as in this case, they are used when the value is not being used.

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.

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

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.)