summaryrefslogtreecommitdiff
path: root/prolog/problems/lists/del_3/en.py
blob: d6e1e3089171a75239b67fb08093f9a37fcba2d4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
name = 'del/3'
slug = 'delete element from list'

description = '''\
<p><code>del(X, L1, L2)</code>: the list <code>L2</code> is obtained from <code>L1</code> by deleting element <code>X</code>.</p>
<pre>
?- del(1, [1,2,3], L).
  L = [2,3].
?- del(2, [1,2,3,2,5], L).
  L = [1,3,2,5] ;
  L = [1,2,3,5].
?- del(X, [1,2,3], L).
  X = 1, L = [2,3] ;
  X = 2, L = [1,3] ;
  X = 3, L = [1,2].
</pre>'''

plan = ['''
<p style="text-align: center;">
    <img style="display: inline-block; width: 40%; border-right: 1px solid lightgray;" src="[%@resource plan_a.svg%]" />
    <img style="display: inline-block; width: 40%;" src="[%@resource plan_b.svg%]" />
</p>
<p>This exercise is very similar to the exercise <code>memb/2</code>, except that this time we also delete
the element we are looking for. Where in the list can element <code>X</code> be hiding?
Remember that a list has two parts: head and tail. Therefore there are two possibilies!</p>
''', '''\
<p>What is the simplest option? Perhaps deleting the first element?</p>
''', '''\
<p>How do I delete from the list's tail? Just divide the list into its head and tail, recursively (as
the problem is one element smaller now) delete from the tail, and at the end don't forget about the
head previously taken away.</p>
''', '''\
<p>Recursive step: if we assume <code>NewTail</code> is the tail with element <code>X</code> already deleted,
then <code>[H|NewTail]</code> is the whole list with element <code>X</code> deleted.</p>
''']

hint = {
    'eq_instead_of_equ': '''\
<p>The operator <code>==</code> is "stricter" than operator <code>=</code> in the sense that
for the latter it is enough to be able to make the two operands equal (unification). Perhaps by using <code>=</code>
you can make the predicate <code>del/3</code> more general (e.g. able to work with output arguments becoming inputs).</p>
<p>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).</p>
''',

    'eq_instead_of_equ_markup': '''\
<p>Perhaps the operator for unification (=) would be better?</p>
''',

    'base_case': '''\
<p><img src="[%@resource base_case.svg%]" /></p>
<p>Did you think of a base case? Where in the list is it the easiest to delete an element?</p>
''',

    'recursive_case': '''\
<p>The base case is ok. However, what about the general recursive case?</p>
''',

    'predicate_always_false': '''\
<p>It seems your predicate is <emph>always</emph> "false". Did you give it the correct name,
or is it perhaps misspelled?</p>
<p>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?</p>
<p>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 <code>[]</code> is equal to a list with
exactly three elements <code>[A,B,C]</code>,
or something similarly impossible).</p>
''',

    'timeout': '''\
<p>Is there an infinite recursion at work here? How will it ever stop?</p>
<p>Or perhaps is there a missing, faulty, or simply incompatible (with the general recursive case) base case?</p>
''',

    'del_from_empty_list_success': '''\
<p>You can't delete an element from an empty list!</p>
<p>If I delete an element from an empty list, this doesn't result in an empty list or anything else, but it
simply shouldn't succeed. You don't even have to include a rule for this as prolog by default acts like that.
You know how prolog loves to say "no"! :)</p>
<p>If that is your base case, rethink it! Where in the list is it the easiest to delete an element?</p>
''',

    'lost_heads': '''\
<p><img src="[%@resource lost_heads.svg%]" /></p>
<p>The element has been successfully deleted, but all the others before it got deleted too, right?
Did you forget to put the head back at the front of the list after returning from recursion?</p>
<p>Try asking the following query:</p>
<p><code>?- del(d, [a,b,c,d,e,f,g], L).</code></p>
''',

    'leading_heads_all_x': '''\
<p><img src="[%@resource leading_heads_all_x.svg%]" /></p>
<p>Did you forget (copy/paste?) and used <code>[X|T]</code> instead of the more general <code>[H|T]</code>
in the recursive case?</p>
<p>Of the following two queries one works and the other doesn't.</p>
<p><code>?- del(d, [d,d,d,d,e,f,g], L).</code></p>
<p><code>?- del(d, [a,b,c,d,e,f,g], L).</code></p>
''',

    'final_hint': '''\
<p>Interesting tidbit. Inserting and deleting an element into/from the list are opposite operations.
Just by playing around with the arguments you can solve <code>del/3</code> using <code>insert/3</code>.</p>
<p>Logically the following holds: deleting element <code>X</code> from list <code>BigList</code> resulting
in list <code>SmallList</code> is the same as <em>inserting</em> element <code>X</code>
into list <code>SmallList</code> to get list <code>BigList</code> as a result. ;)</p>
''',
}