All skeleton files are provided in the assignments folder. Please fork this repo to get started. For what forking means or how to fork a repo, please visit this github help page for a detailed explanation.
Again, please feel free to post questions on github Issues page for the repo.
Transform a list, possibly holding lists as elements into a 'flat' list by replacing each list with its elements (recursively).
Example:
?- flattenList(L, [a, [b, [c, d], e]]).
L = [a, b, c, d, e]
?- flattenList(L, [1, [1, 2], [3, 4], [5, [6, [7, 8]]]]).
L = [1,1,2,3,4,5,6,7,8]
?- flattenList(L, [[[[9, 10], 11], 12], [1, 2], [3, 4], [5, [6, [7, 8]]]]).
L = [9,10,11,12,1,2,3,4,5,6,7,8]
?- flattenList([1, 2, 3], [1, [2, 3]]).
true- Establish the base case for recursion first and build up the logic
- Don't call your rule
flatten/2, since it's a predefined predicate - Use
[H|T]to destruct a list in to the head and tail - Use the predefined predicates
is_list/1andappend/3
Produce a list that contains 2 copies of every element in the original list in order.
Example:
?- duplicate(L, [1, 2, a, b]).
L = [1,1,2,2,a,a,b,b]
?- duplicate([1,1,2,2,a,a,b,b], [1, 2, a, b]).
true
?- duplicate([1,1,2,2,a,a,b,b], L).
L = [1,2,a,b]- Establish the base case for recursion first and build up the logic
- Use
[H|T]to destruct a list in to the head and tail - Use the predefined predicate
append/3
If you are feeling ambitious, you can write a more generalized version of the function that allows you to specify how many copies of each element you want in the duplicate list.
Example:
?- duplicateN(L, [1, 2, a, b], 3).
L = [1,1,1,2,2,2,a,a,a,b,b,b]
?- duplicateN([1,1,1,2,2,2,a,a,a,b,b,b], [1, 2, a, b], 3).
true
?- duplicateN([1,1,1,2,2,2,a,a,a,b,b,b], L, 3).
L = [1,2,a,b]- Aside from the same hints above, you should define a rule that appends
Ncopies on an item to a list. Something likeprependN(NewList, N, List, Item)
Define predicates and/2, or/2, nand/2, nor/2, xor/2, and equ/2 (for logical equivalence) which succeed or fail according to the result of their respective operations; e.g. and(A,B) will succeed, if and only if both A and B succeed. Note that A and B can be Prolog goals (not only the constants true and fail).
A logical expression in two variables can then be written in prefix notation, as in the following example: and(or(A,B),nand(A,B)).
Now, write a predicate table/3 which produces the truth table of a given logical expression in two variables.
Example:
?- table(A, B, and(A, B)).
A = true
B = true
?- table(A, B, and(or(A,B),nand(A,B))).
A = true
B = false
A = false
B = true
?- table(A, B, or(and(or(A,B),nand(A,B)), or(nor(A, B), xor(A, B)))).
A = true
B = false
A = true
B = false
A = false
B = true
A = false
B = true
A = false
B = false
%% Same Example as above, except we now restrict A to false
?- A = false, table(A, B, or(and(or(A,B),nand(A,B)), or(nor(A, B), xor(A, B)))).
A = false
B = true
A = false
B = true
A = false
B = false-
the
bind/1rule defines the domain for A and B. In this case, we restrict bothAandBto boolean values oftrueandfalse. -
Remember from lecture that
.in Prolog is equivalent to a logical or and,is equivalent to a logical and. Sobind(A)specifies thatAcan betrueorfalse
Write a predicate degree(Deg, Node, Graph) that determines the degree, or the number of outgoing edges, of a given node.
Graph is a tuple of (Vertices, Edges), where Vertices is a list of atoms that represent vertices in the graph, and Edges is a list of tuples of 2 atoms that specify a directed edge.
Example:
?- degree(N, a, ([a, b, c, d], [(a, b), (b, c), (c, d), (d, a), (a, c), (b, d)])).
N = 2The query asks what's the degree of atom a, in the graph that contains 4 nodes (a, b, c, d), and 6 directed edges (a -> b, b -> c, c -> d, d -> a, a -> c, b -> d)
In this case the a has 2 outgoing edges, a -> b and a -> c, so the answer should be 2.
Alteratively, you can also ask which nodes have a specific degree.
degree(2, N, ([a, b, c, d], [(a, b), (b, c), (c, d), (d, a), (a, c), (b, d)])).
N = a
N = b
degree(1, N, ([a, b, c, d], [(a, b), (b, c), (c, d), (d, a), (a, c), (b, d)])).
N = c
N = d- Establish the base case for recursion first and build up the logic
- Use
degree(N, Node, (Vertices, [(V1, V2)|Edges]))to deconstruct the arguments into variables you can use - Use
member(N, List)predicate to check to see ifNodeis a valid vertex - Use
ispredicate to compute the degree, as we did in the lecture when computing the sums and averages of lists