From ca743bffb497dea794950bf2bbda45e3bb4c936b Mon Sep 17 00:00:00 2001 From: Aleksander Sadikov Date: Sat, 27 Aug 2016 03:31:18 +0200 Subject: English translation for conc/3 added. --- prolog/problems/lists/conc_3/en.py | 112 ++++++++++++++++++++++++++++++++++++- 1 file changed, 111 insertions(+), 1 deletion(-) (limited to 'prolog/problems/lists/conc_3/en.py') diff --git a/prolog/problems/lists/conc_3/en.py b/prolog/problems/lists/conc_3/en.py index e25ae32..2e74e5e 100644 --- a/prolog/problems/lists/conc_3/en.py +++ b/prolog/problems/lists/conc_3/en.py @@ -10,4 +10,114 @@ description = '''\ X = [1,2,3]. ''' -hint = {} +plan = ['''\ +

+''', '''\ +

Let's start with an easy question. What do I get if I concatenate an empty list and a list L2?

+''', '''\ +

Now, assume that the first list has exactly one element. Let's temporarily take it out which leaves us +with an empty list. But wait! Isn't this situation now similar to the one we dealt with before? Of course, we just +reduced the problem into a smaller one (by one element smaller). Let recursion solve this smaller problem. Just don't +forget to expand the recursion's result with the element you have taken out at the beginning...

+''', '''\ +

Declarative/logic reasoning: Assume the first list L1 has head H and tail +T. If the recursive result of concatenating T and L2 is some list +L3, and if we add element H at the beginning of list L3, what do we get? +A concatenation of L1 and L2!

+'''] + +hint = { + 'eq_instead_of_equ': '''\ +

The operator == is "stricter" than operator = in the sense that +for the latter it is enough to be able to make the two operands equal (unification). Perhaps by using = +you can make the predicate rev/2 more general (e.g. able to work with output arguments becoming inputs).

+

Of course, you can also solve the exercise without explicit use of either of these two operators, just +remember that unification is implicitly performed with the predicate's arguments (head of clause).

+''', + + 'eq_instead_of_equ_markup': '''\ +

Perhaps the operator for unification (=) would be better?

+''', + + 'base_case': '''\ +

Did you think of a base case? What is the simplest possible case? +What's the answer if, for example, the first list is empty? (Just the first list should be empty, +the second one can be arbitrary.)

+''', + + 'base_case_arbitrary': '''\ +

How can the result of concatenating two lists be an arbitrary list (a variable without an assigned value)?

+

If your base case is similar to conc([], L, _), +then you should rethink it: what is the result of the concatenation, what do you return as the result? +The base case always fully specifies the result, usually there are no unknowns (_ +or variables without assigned values) in what is being returned as the result.

+''', + + 'predicate_always_false': '''\ +

It seems your predicate is always "false". Did you give it the correct name, +or is it perhaps misspelled?

+

If the name is correct, check whether something else is misspelled, perhaps there is a full stop instead of +a comma or vice versa, or maybe you typed a variable name in lowercase?

+

It is, of course, also possible that your conditions are too restrictive, or even impossible to satisfy +(as would be, for example, the condition that an empty list [] is equal to a list with +exactly three elements [A,B,C], +or something similarly impossible).

+''', + + 'timeout': '''\ +

Is there an infinite recursion at work here? How will it ever stop?

+

Or perhaps is there a missing, faulty, or simply incompatible (with the general recursive case) base case? +Are you maybe reducing the first list, but your base case stops with an empty second list (or vice versa)?

+''', + + 'second_list_iteration': '''\ +

It seems you're processing (reducing) the second list. The mechanism at work is correct, however, +the final ordering of the elements is not. It's better to process the first list in this way and +leave the second one as is.

+

There's another reason to process the first list: in this way the solution of this essential exercise +will be the same for everyone, and we'll be able to use conc/3 in a standardised way. This +will be very important later on.

+''', + + 'insertion_into_second_list': ''' +

Is your recursive call of the form conc(T, [H|L2], ...)? +Don't insert the first list's head into the second list as this will result in the wrong ordering +of the elements. Let the recursion alone take care of concatenating the first list's tail +T with the second list L2, and then, when returning the complete result, +add the first list's head H into its proper place.

+''', + + 'two_heads': '''\ +

Do you really need two list heads? Are you trying to reduce both lists? This is not a good idea, it is +difficult to solve the exercise in this way. Rather simply reduce the first list only, and leave the +other list as is.

+''', + + 'two_heads_markup': '''\ +

Do you really need two list heads?

+''', + + 'forcing_result_onto_recursion': ''' +

Don't force the result onto recursion, don't tell it what it should return. Just assume it will do its job. +If this assumption is correct, then the rule will work for a larger case.

+

Is your recursive call of the form conc(T, L2, [H|...])? This forces the recursive call to +return the head at the start of the concatenated list. But it doesn't know of this head, because you just +took it away! Inserting the head into the result, returned by the recursive call, is your job. To put it shortly, +insert H outside of the recursive call.

+''', + + 'final_hint': '''\ +

Predicate conc/3 will be useful for much more than just concatenating two lists. +Among other things it can be used "in the other direction" -- for dividing a list into two parts. Try the +following queries:

+

?- conc(L1, L2, [a,b,c,d]).

+

?- conc([X,Y], L2, [a,b,c,d,e,f]).

+

Did you notice that the second query returned the first two elements from the list [a,b,c,d,e,f]?

+

Furthermore, conc/3 is useful to search for patterns in a list, e.g.:

+

?- conc(_, [X,X|_], [a,b,c,c,d,e,f,f,g,h,h]).

+

Right, this query finds all possibilities where two identical elements appear one after the other in a list +(pattern X,X). Basically the query said that "there are some elements (possibly zero) in front, then follow two +identical elements, and then again some elements (possibly zero) at the end."

+

There are many other usages of conc/3, you will discover them along the way.

+''', +} -- cgit v1.2.1