COM2003: Prolog Lab Class 3 Using CUT / Further exercises in Recursion Red and Green CUT Copy the lab class file “cuts_red_green.pl” into your own filespace. The file contains a definition for a procedure howbig/2, which takes a list of numbers for its first argument, and returns a list of the same length as the first, but with the numbers replaced by atoms large, small or medium, depending on whether the corresponding number is more than 10, less than or equal to 5, or in between, respectively. The definition uses no cuts, and will work correctly even if the clauses were reordered. The file also contains identical definitions of predicates howbig_green/2 and howbig_red/2 for you to modify. Green cuts: Modify the definition of howbig_green/2 to capture determinism (and hence avoid unnecessary backtracking), by adding green cuts, i.e. cuts that do not modify the declarative meaning of your code. Red cuts: Next, modify the definition of howbig_red/2 to shorten its definition, by using red cuts to allow the omission of tests, where possible. Test that your definitions work as intended, including under backtracking. Recall that the standard diagnostics for red vs. green cuts is whether the answers returned by the code changes if (i) cuts are removed, or (ii) clauses are reordered.
Recursion — further exercises Write and test your own definitions for the following predicates. As before, check that your definitions are well-behaved under backtracking. If you don’t manage to complete these exercises during the lab class session, you should finish them later, as part of your study for the module (and preparation for the exam). Model solutions will be published in due course. 1. in_list/2, where in_list(A,L) succeeds just in case A is an element of the list L, e.g. so a call in_list(b,[a,b,c]) should succeed, whilst in_list(g,[a,b,c]) should not. Investigate how your definition behaves when the value of A is unspecified. 2. ordered/1, where ordered(L) succeeds just in case the list of integers L are in ascending order (e.g. [1,3,3,7,19]). 3. prefix/2, where prefix(L1,L2) succeeds just in case list L1 is a prefix of the list L2, e.g. where L2 = [a,b,c,d,e,f] and L1 is some prefix of L2 such as [a,b] or [a,b,c,d]. Can your definition be used non-deterministically to select alternative prefixes of L2? 4. suffix/2, where suffix(L1,L2) succeeds just in case list L1 is a suffix (or ‘some tail’) of the list L2, e.g. if L2 = [a,b,c,d,e,f], then L1 might be [e,f] or [c,d,e,f]. 5. nth/3, where nth(N,As,A) succeeds just in case A is the Nth element of the list As. Investigate whether your definition can be used when any one of the three argument values is uninstantiated.
6. concat/3, where concat(L1,L2,L3) succeeds just in case L3 is the concatenation of lists L1 and L2, e.g. if L1 = [a,b] and L2 = [c,d], then L3 = [a,b,c,d]. Your definition must work where L1 and L2 are initially instantiated but L3 is not. Investigate its behaviour when only L3 is instantiated. 7. dividelist/3, where a call dividelist(L1,L2,L3) will serve to partition the members of list L1 between lists L2 and L3, e.g. dividelist([a,b,c,d,e],[a,c,e],[b,d]). Check that your definition works okay irrespective of whether the length of L1 is even in number or odd. 8. draw_triangle/1, which draws a triangle of asterisks, e.g. for draw_triangle(3) we would get the result immediately below. To print a single asterisk, you can use write(â€™*â€™), and to print a newline, you can use the goal nl. *** ** * Consider how you might modify your code so that the triangle prints the other way up, i.e. as shown immediately below. NOTE: you can achieve this with only a minor change to your code â€” you just need to see the trick! * ** ***