Prolog - 'Member Of' List - list

I have a function called member that is supposed to take as arguments:
1) a name
2) a list of names.
The list of names is already defined in my program, so I want to be able to call the method with a name and the list that's already initialized in the program.
For example, my Prolog program contains...
namesList(mike,joe,bob,jill).
member(Element, [Element|_]):-!.
member(Element, [_|Tail]):-member(Element,Tail).
So, when I'm at a Prolog prompt and type in member(mike,namesList). Prolog should output true, but instead prints false.
Am I calling the function correctly, or can I not use an already instantiated list?

First, Prolog doesn't have functions: it has predicates.
Second, A non-empty prolog list is written using square brackets — [a,b,c,d] with the empty list denoted by the atom []. Lists are actually represented by the structure ./2, where the first argument is the first item (the head) of the list and the second argument is the remainder of the list, either another non-empty list, or the empty list itself. It's what the compiler writers like to call syntactic sugar. So
[a] is exactly equivalent to .(a,[]).
[a,b] is exactly equivalent to .(a,.(b,[])).
[a,b,c] is exactly equivalent to .(a,.(b,.(c,[])))
etc.
And
[A|B] is exactly equivelent to .(A,B).
You can see why the square brackets notation is a little easier to use.
So...you could store your names list this:
names_list( [mike,joe,bob,jill] ).
in which case, you could say:
?- names_list( Names ) , member(mike,Names) .
true.
However...You might find it easier if you maintained your names in a more...prolog-like manner:
name( mike ) .
name( joe ) .
name( bob ) .
name( jill ) .
Then...
You can check for existence in the usual way:
?- N = sam , name(N) ,
false.
Or, you can iterate over them via backtracking:
?- name(N).
N = mike ;
N = joe ;
N = tim ;
N = jill.
And, if you really need them as a list, it's easy to get them in that form:
?- findall(N,name(N),Ns).
Ns = [mike, joe, tim, jill].
Finally, one should note the list of names could be extracted from your
names_list( mike , joe , bob , jill ).
but it's not exactly the most elegant thing in the world:
extract( Name , Arguments ) :-
atom(Name) ,
current_functor(Name,Arity) ,
length(Arguments,Arity) ,
Goal =.. [Name|Arguments] ,
callable(Goal) ,
call(Goal)
.
Once you have that, you can say:
?- extract(names_list,Names) , member(mike,Name).
true.

Related

Deep copy of a list in Prolog

I am trying to copy a list so that the original list is not changed by whatever operations I perform on the new list. I have looked at prolog, copying lists and Prolog - copy a piece of list. However, neither of these options generates a list that is "independent" from its "parent".
Coming from an imperative background, some Prolog concepts are hard to grasp and I'm sure I'm missing something here. So my question is is it possible to create a deep copy of a list in Prolog?
Thank you in advance.
A list is just a term dressed in fancy clothing.
[] is a simple atom.
[a] is syntactic sugar for the term .(a,[])
[a,b] is syntactic sugar for the term .(a,.(b,[])).
[H|T] is syntactic sugar for the term .(H,T)
That's all there is to it. Conserves parentheses and periods, it does.
So what you're talking about really has nought to do with lists, but everything to do with terms. If the term in question is fully bound -- meaning it and, recursively, any sub-terms, do not contain any non-unified variables, the term is immutable. But if it contains any unbound variables, it's mutable.
So, what you're talking about is doing a recursive tree walk to clone a term, replacing any unbound variables with a fresh copy. The trick is that you need to map each variable encountered with its replacement. so something like [A,A,B,B,foo(A,B,C),C] comes out as [X,X,Y,Y,foo(X,Y,Z),Z] and not [V1,V2,V3,V4,foo(V5,V6,V7),V8].
Luckily, Prolog comes with build-in tooling for that: copy_term/2.
But I imagine your instructor is not looking for you to be using that.
Traversing an arbitrary term is not difficult. Something along these lines (don't have a Prolog convenient to hand at the moment):
clone_deep( T , C ) :- clone_deep( T, [], C, _ ).
% T: source term
% S: symbol table
% C: cloned term
% S1: [possibly] extended symbol table
clone_deep( T , S , C, S1 ) :-
var(T), % term is a variable
map_var(T,S,C,S1) % fetch/add its mapping to the symbol table.
.
clone_deep( T , S , T , S ) :-
atomic(T) % term is atomic (number, atom, etc.)
.
clone_deep( T , S , C, S1 ) :-
compound(T), % term is a compound term like foo() or foo(X,Y).
T =.. [Functor|Args], % decompose it into its functor and its argument list
clone_deep(Args,S,Args1,S1), % recursively clone its arguments
C =.. [Functor|Args1] % recompose the new compound term
.
% recursively run down the list of symbol mappings to find the self-same variable
% add it if not found.
map_var( V , [ X:C | S ] , C , [ X:C | S ] ) :- X == V, !. % V is the same ref as X -- already in symbol table
map_var( V , [ X:Y | S ] , C , [ X:Y | Z ] ) :- X \== V, !, % V and X are different refs
fresh_symbol(V,S,C,Z). %
map_var( V , [] , C , [ X:C ] ). % not yet mapped var.

Understanding Prolog's empty lists

I am reading Bratko's Prolog: Programming for Artificial Intelligence. The easiest way for me to understand lists is visualising them as binary trees, which goes well. However, I am confused about the empty list []. It seems to me that it has two meanings.
When part of a list or enumeration, it is seen as an actual (empty) list element (because somewhere in the tree it is part of some Head), e.g. [a, []]
When it is the only item inside a Tail, it isn’t an element it literally is nothing, e.g. [a|[]]
My issue is that I do not see the logic behind 2. Why is it required for lists to have this possible ‘nothingness’ as a final tail? Simply because the trees have to be binary? Or is there another reason? (In other words, why is [] counted as an element in 1. but it isn't when it is in a Tail in 2?) Also, are there cases where the final (rightmost, deepest) final node of a tree is not ‘nothing’?
In other words, why is [] counted as an element in 1. but it isn't when it is in a Tail in 2?
Those are two different things. Lists in Prolog are (degenerate) binary trees, but also very much like a singly linked list in a language that has pointers, say C.
In C, you would have a struct with two members: the value, and a pointer to the next list element. Importantly, when the pointer to next points to a sentinel, this is the end of the list.
In Prolog, you have a functor with arity 2: ./2 that holds the value in the first argument, and the rest of the list in the second:
.(a, Rest)
The sentinel for a list in Prolog is the special []. This is not a list, it is the empty list! Traditionally, it is an atom, or a functor with arity 0, if you wish.
In your question:
[a, []] is actually .(a, .([], []))
[a|[]] is actually .(a, [])
which is why:
?- length([a,[]], N).
N = 2.
This is now a list with two elements, the first element is a, the second element is the empty list [].
?- [a|[]] = [a].
true.
This is a list with a single element, a. The [] at the tail just closes the list.
Question: what kind of list is .([], [])?
Also, are there cases where the final (rightmost, deepest) final node of a tree is not ‘nothing’?
Yes, you can leave a free variable there; then, you have a "hole" at the end of the list that you can fill later. Like this:
?- A = [a, a|Tail], % partial list with two 'a's and the Tail
B = [b,b], % proper list
Tail = B. % the tail of A is now B
A = [a, a, b, b], % we appended A and B without traversing A
Tail = B, B = [b, b].
You can also make circular lists, for example, a list with infinitely many x in it would be:
?- Xs = [x|Xs].
Xs = [x|Xs].
Is this useful? I don't know for sure. You could for example get a list that repeats a, b, c with a length of 7 like this:
?- ABCs = [a,b,c|ABCs], % a list that repeats "a, b, c" forever
length(L, 7), % a proper list of length 7
append(L, _, ABCs). % L is the first 7 elements of ABCs
ABCs = [a, b, c|ABCs],
L = [a, b, c, a, b, c, a].
In R at least many functions "recycle" shorter vectors, so this might be a valid use case.
See this answer for a discussion on difference lists, which is what A and Rest from the last example are usually called.
See this answer for implementation of a queue using difference lists.
Your confusion comes from the fact that lists are printed (and read) according to a special human-friendly format. Thus:
[a, b, c, d]
... is syntactic sugar for .(a, .(b, .(c, .(d, [])))).
The . predicate represents two values: the item stored in a list and a sublist. When [] is present in the data argument, it is printed as data.
In other words, this:
[[], []]
... is syntactic sugar for .([], .([], [])).
The last [] is not printed because in that context it does not need to. It is only used to mark the end of current list. Other [] are lists stored in the main list.
I understand that but I don't quite get why there is such a need for that final empty list.
The final empty list is a convention. It could be written empty or nil (like Lisp), but in Prolog this is denoted by the [] atom.
Note that in prolog, you can leave the sublist part uninstantiated, like in:
[a | T]
which is the same as:
.(a, T)
Those are known as difference lists.
Your understanding of 1. and 2. is correct -- where by "nothing" you mean, element-wise. Yes, an empty list has nothing (i.e. no elements) inside it.
The logic behind having a special sentinel value SENTINEL = [] to mark the end of a cons-cells chain, as in [1,2,3] = [1,2|[3]] = [1,2,3|SENTINEL] = .(1,.(2,.(3,SENTINEL))), as opposed to some ad-hoc encoding, like .(1,.(2,3)) = [1,2|3], is types consistency. We want the first field of a cons cell (or, in Prolog, the first argument of a . functored term) to always be treated as "a list's element", and the second -- as "a list". That's why [] in [1, []] counts as a list's element (as it appears as a 1st argument of a .-functored compound term), while the [] in [1 | []] does not (as it appears as a 2nd argument of such term).
Yes, the trees have to be binary -- i.e. the functor . as used to encode lists is binary -- and so what should we put there in the final node's tail field, that would signal to us that it is in fact the final node of the chain? It must be something, consistent and easily testable. And it must also represent the empty list, []. So it's only logical to use the representation of an empty list to represent the empty tail of a list.
And yes, having a non-[] final "tail" is perfectly valid, like in [1,2|3], which is a perfectly valid Prolog term -- it just isn't a representation of a list {1 2 3}, as understood by the rest of Prolog's built-ins.

Prolog: square numbers in a list

Ho do I square numbers in a list in prolog?
The list can contain numbers, atoms and lists.
for example: [a,b,2,3,4,[3],[c,d,9]] and the answer should be [a,b,4,9,16,[3],[c,d,9]].
As we see in the answer it should be a shallow squaring of the values in the list.
2->4
3->9
4->16
What I have tried so far,
square([],X).
square([A|B],X):-number(A), A is A*A, square(B,X).
X will contain squared values. Base case is when empty list is received. I check if head (A) is a number then I go ahead square the number and change A to A * A. Then go ahead and call the square function for remaining part B.
Please suggest where I am doing wrong.
EDIT: Correct answer as follows. By aBathologist. Please read his comment for detailed explanation.
squared_members([], []).
squared_members([L|Ls], [SqrdL|SqrdLs]) :-
number(L),
SqrdL is L * L,
squared_members(Ls, SqrdLs).
squared_members([L|Ls], [L|SqrdLs]) :-
\+number(L),
squared_members(Ls, SqrdLs).
And
squared_members([], []).
squared_members([L|Ls], [M|Ms]) :-
( number(L)
-> M is L * L, squared_members(Ls, Ms)
; M = L, squared_members(Ls, Ms)
).
We're defining a predicate which describes the relationship between one list, A, and another list, B: B should have all the same elements as A, except that any number in A should be squared in B.
Where you've gone wrong:
Your ground condition, square([],X), says that when A is empty, then B is anything (so, for instance, even something like square([], 15) is true). But this doesn't capture the meaning we're after, since the second argument should be a list with the same number of members as the first. That is, when the first list is empty then the second list should be empty.
The same problem occurs with your recursive rule, since, at each iteration, an undetermined variable is passed along, and there is never anything said about the relationship between the first list and the second.
This rule will only succeed if the first element of alist is a number. In the case where the first element is, e.g., a (like in your example), number(a) will be false. Since there are no additional rules for the predicate, it will simply be false unless every member of the first list is a number.
Variables in Prolog must always have the same, consistent value throughout the context in which they appear. They function like variables in arithmetic formula. The formula a + b - b = a is true for any values of a and b but *only if a and b are each assigned one, consistent value throughout the equation. The same is true in Prolog statements of the form <variable> is <expression>. What you've written says a = a * a which cannot be the case.
*What you're definition says is, roughly, this: The list B is a squared version of the list A if A is an empty list and B is anything OR if the first element of A is a number, and that number is equal to itself squared, and B is a squared version of the rest of A.
Here's one possible solution:
squared_members([], []).
squared_members([L|Ls], [SqrdL|SqrdLs]) :-
number(L),
SqrdL is L * L,
squared_members(Ls, SqrdLs).
squared_members([L|Ls], [L|SqrdLs]) :-
\+number(L),
squared_members(Ls, SqrdLs).
Notice that this definition is able to establish a meaningful relationship between the two lists by having them either share variables, or contain elements related by a chain of relations between variables (i.e., SqrdL is related to L by virtue of being L * L). This definition has one more clause then yours, which enables it to take account of the members of a list which are not numbers: those are added to the second list unaltered.
An alternative definition, using If-Then-Else notation for cleaner expression, would be the following:
squared_members([], []).
squared_members([L|Ls], [M|Ms]) :-
( number(L)
-> M is L * L, squared_members(Ls, Ms)
; M = L, squared_members(Ls, Ms)
).

Prolog if/else statement with recursion

I'm new to prolog and I'm trying to figure out how I can use if/else statement and recursion. To illustrate, I've written a simple prolog program. The program is useless (in that its functionality is useless), but it helps me illustrate my problem. The program takes a list, examines the head of the list, sees if it's the last element; if it's not, it adds the head to a temporary list variable and runs the program in recursion using the Tail of the list. It should output the list in the end. The program:
gothrough([H|T], B, C):-
append(B,H,B),
( (T == [])
-> C=B
; gothrough(T, B, C)
).
The call: gothrough([sample, phrase, here], [], C).
Expected output: C = [sample, phrase, here]
Current output: no
Any help on what I'm doing wrong?
Thanks!
From your comments I understand that you misunderstand how append (and Prolog in general) works.
This is not true at all: "if B = [yesterday] and H = [today], then append(B, H, B) = [yesterday, today]".
append(B, H, B) means "appending H to B yields B again". This is only possible if H is an empty list.
The key thing to understand is that both Bs in append(B, H, B) are the same, they must have the same value. It's like variables in algebra - all Xs in an equation means the same value.
You should use different name for the output variable, like append(B, H, Bnew) - then it will make more sense.
The first problem is append(B, H, B) which for most inputs doesn't make sense.
The second problem is that the consequence and alternative of an if-then-else, i.e. the parts after -> and after ; must both be Prolog goals (statements). C is not a goal. You may have meant C=B, though it's hard to tell because I find it hard to understand what your program is doing.
You're getting a no because append(B,H,B) fails unless H is []; remember, these are clauses, not assignments. And since you never bind anything to C, it will never have a value in it if your statement was ever proved.
This will accomplish your task:
gothrough([],L,L).
gothrough([H|T], B, C) :- gothrough(T,B,Cx), append([H],Cx,C).
This can be done even more simply:
gothrough([], []).
gothrough([H|T], [H|X]) :-
gothrough(T, X).
The first rule matches your empty list condition, which then forces the end of the recursion/the list to be built.
The second rule matches everything but an empty list, in which case the head H is appended onto X, where X is the result of list obtained from recursing the tail. ie. you don't need to use the append predicate - list appending is built into prolog.
?- gothrough([simple, phrase, here], X).
X = [simple, phrase, here].
This solution also uses one less variable.

prolog list of pairs

I have an input of a list of pairs:
[[abs_(p,X,Y,Z),abs_(f,X,Y,Z)],[abs_(p,X,Y,Z),abs_(l,Z,P)]]
I want check if a pair have the same number of arguments, in this case yes:
[abs_(p,X,Y,Z),abs_(f,X,Y,Z)]
In the second case the answer is no.
This is just an example because more generally, I want to know which pair have the same number of arguments. The output for the input should be:
[[abs_(p,X,Y,Z),abs_(f,X,Y,Z)]
What do I have to do?
run( [], Tail) :- Tail=[].
run( [ [First,Second] | Tail ], Output ) :- First =.. List1, Second =.. List2,
length(List1,N1), length(List2, N2), N2 is N1, !, run(Tail, Tail2),
append( [ [First | [Second]] ], Tail2, Output ).
run( [H|T], Output ) :- run(T, Output).
First rule is base case. Second rule checks the number of arguments in first pair if its same run the recursive call and append the output from recursive call with and this pair to Output. Because of cut if N2 equals N1 it doesn't call third rule. And third rule discard the unmatched pair and call itself with tail of the list. Hope it helps.
Prolog provides a strange infix operator =.. called "univ" which converts between compound terms and a list that begins with the functor followed by the arguments to that functor.
Hence a Prolog query something like this:
?- abs_(p,X,Y,Z) =.. L.
L = [abs_,p,X,Y,Z]
yes
So I would use length/2 on the lists produced by the "univ" operator to check that two compound terms have an equal number of arguments.
You can also use pattern matching to break each pair into terms, and use the functor predicate to check the arity of those terms.