/* CS1621 Fall 2005 Some short prolog programs demonstrating lists and more recursion */ member(X, [X|_]). member(X,[_|Y]) :- member(X,Y). /* predicate to test if a value is a member of a list. Both statements in this predicate use the anonymous variable. The idea is simple: In the first statement, if the item searched for is at the front of the list, we don't care what is in the rest of the list. However, if the first statement does not match, then we no longer care what the front of the list is and we try the second statement. */ /* This version of member is interesting and it demonstrates the versatility of Prolog. It can be used to either find a value in a list (if X is instantiated) or to enumerate all of the values in the list (if X is uninstantiated). However, it can also cause problems if both X and the list are uninstantiated -- it recurses without end (due to the same left recursion mentioned in recurse.pl */ newmember(X, Y) :- nonvar(X), nonvar(Y), member(X,Y). /* new verion of member to make sure both arguments are nonvariables. However, when done this way, the second form of member does not work. Another modification could be to make sure the second argument is a list */ islist([]). /* predicate to see if an object */ islist([_|B]) :- islist(B). /* is a list */ /* predicate to find the length of a list */ listlen([],0). /* empty list has a length of 0 */ listlen([H|T],N) :- listlen(T,N1), N is N1 + 1. /* nonempty list has */ /* a length of 1 plus the length of its tail */ /* Note: The variable H is never used except as a placeholder, and thus could be replaced by the anonymous variable. In fact, note that the compiler gives a warning about this, calling it a "Singleton variable". If you see this warning in your pro- grams, you should think either that it should be an _ or that you may have a logic error */ /* predicate to append two lists together to form a new list. This is typically predefined in Prolog but it is interesting to look at how it can be defined. It is also interesting to see how it can be used. Try it with various arguments (instantiated and uninstantiated) to see the results */ append([],L,L). append([X|L1],L2,[X|L3]) :- append(L1,L2,L3). intsupto(N, L) :- nonvar(N), N > 1, N1 is N - 1, intsupto(N1,L1), append(L1, [N], L). intsupto(N, L) :- nonvar(N), N = 1, L = [1]. /* interesting predicate to generate a list of the integers from 1 up to N. N must be instantiated, then the int list up to N-1 is formed, then N is appended to the end of it to form L. Note that since L is the final answer, and since variables are not changed once they are instantiated, L is the last variable instantiated. */ /* Note that in the version above, the two rules are mutually exclusive, since the value of N is tested. However, we can take advantage of the fact that the Prolog database is searched from top to bottom to avoid the tests, as shown in the alternate version below. */ ints2upto(1,[1]). ints2upto(N,L) :- nonvar(N), N1 is N-1, ints2upto(N1,L1), append(L1,[N],L).