During some playing around with different list predicates in SWI-Prolog (SWISH), I was trying to check if an atom a
was part of the list List1
which I defined in the program as List1 = [a,b,c,d]
.
I formulated my query as member(a, List1).
, expecting something along the lines of a simple 'yes' (just as it shows in this youtube video at 59:25), but instead I got a warning
Singleton variables: [List1]
and an error
No permission to modify static procedure `(=)/2'
From what I understand from looking this up online, the warning is not that important here. I do not understand, however, why I get an error message while a
is clearly a member of List1
.
I tried this in two different ways:
1) By adding List1 = [a,b,c,d].
to the program and querying with member(a,List1).
(which resulted in the error above);
2) By passing List1 = [a,b,c,d]
directly to the interpreter and then using the same query ( member(a,List1).
), which resulted in an endless amount of results where a
shifted positions in the Head of the list, like so:
List1 = [a|_1186]
List1 = [_1062, a|_1070]
List1 = [_1062, _1068, a|_1076]
List1 = [_1062, _1068, _1074, a|_1082]
List1 = [_1062, _1068, _1074, _1080, a|_1088]
Is this something about the specific Prolog version I am using, or am I missing something very simple?
EDIT
I was aware that a similar question was posed here , but I did not manage to fully understand the answer (nor the question) as it was immediately going about things as dynamic
which I have not yet encountered in Prolog. I was looking for a more general, more 'high-level' answer which I have found by posing this question.
I defined in the program as
List1 = [a,b,c,d].
This is not what it does. What it does is define a predicate =/2
:
2 ?- write_canonical( (List1 = [a,b,c,d]) ). =(_,[a,b,c,d])
(The ?-
, or 2 ?-
that you see there, is the interactive prompt of a Prolog system; SWI Prolog in my case. Whatever goes on that line after it is what I have typed; and then on the next line we see the system's response).
Of course this tramples over the already existing built-in definition for =
as the unification predicate. And hence the error which says precisely that. And yes, it is important.
To "define" a list in Prolog, we can define a predicate
8 ?- [user].
p([1,2,3,4]).
such that we can then query
9 ?- p(List1).
List1 = [1, 2, 3, 4].
and work further with List1
,
10 ?- p(List1), member(A,List1).
List1 = [1, 2, 3, 4],
A = 1 ;
List1 = [1, 2, 3, 4],
A = 2 ;
List1 = [1, 2, 3, 4],
A = 3 ;
List1 = [1, 2, 3, 4],
A = 4.
We could also just directly specify the list as a sub-goal of our query,
11 ?- List1 = [1,2,3,4], member(A,List1).
List1 = [1, 2, 3, 4],
A = 1 ;
List1 = [1, 2, 3, 4],
A = 2 ;
List1 = [1, 2, 3, 4],
A = 3 ;
List1 = [1, 2, 3, 4],
A = 4.
making use of the predicate =/2
, as opposed to redefining it, which is forbidden.
The above answers your 1)
. As for 2)
, you aren't telling us the whole truth. What you appear to have done, was to first make a query
12 ?- List1 = [a,b,c,d].
List1 = [a, b, c, d].
which is fine and dandy; and then make another query,
13 ?- member(a,List1).
List1 = [a|_G2181] ;
List1 = [_G2180, a|_G2184] ;
List1 = [_G2180, _G2183, a|_G2187] ;
List1 = [_G2180, _G2183, _G2186, a|_G2190] ;
List1 = [_G2180, _G2183, _G2186, _G2189, a|_G2193] .
Prolog prompt is not a REPL. We don't make definitions at it. We make queries.