name = 'min/2' slug = 'Poišči najmanjši element v danem seznamu' description = '''\
min(L, Min)
: Min
je najmanjši element v seznamu L
.
?- min([5,4,1,6], M). M = 1. ?- min([3,2,2], M). M = 2.''' plan = ['''\
Kot vedno, poskusi prevesti na manjši problem. Recimo, da že imaš najmanjši element v repu seznama...
''', '''\Najmanjši element v repu (seznamu brez glave H
) primerjaj z vrednostjo glave H
, tisti,
ki je manjši zmaga in ga vrneš!
Če je podani seznam L
sestavljen iz glave H
in repa T
ter predpostavimo,
da je najmanjši element v T
enak MinT
ter dalje velja še, da je vrednost H
manjša od MinT
, potem je H
najmanjši element v L
. Ali pa velja, da je
vrednost H
večja od MinT
, v tem primeru pa je MinT
najmanjši element v
L
.
Operator ==
je strožji od operatorja =
v smislu, da je za slednjega dovolj,
da elementa lahko naredi enaka (unifikacija). Morda z uporabo =
narediš predikat
memb/2
delujoč tudi v kakšni drugi smeri.
Seveda pa lahko nalogo rešiš brez obeh omenjenih operatorjev, spomni se, da lahko unifikacijo narediš implicitno že kar v argumentih predikata (glavi stavka).
''', 'eq_instead_of_equ_markup': '''\Morda bi bil bolj primeren operator za unifikacijo (=)?
''', 'base_case': '''\Si pomislil na robni pogoj? Kaj je najkrajši seznam, ki ima očiten najmanjši element?
''', 'recursive_case': '''\Robni primer deluje. Kaj pa rekurzivni, splošni, primer?
''', 'predicate_always_false': '''\Vse kaže, da tvoj predikat vedno vrne "false". Si mu dal pravilno ime, si se morda pri imenu zatipkal?
Če je ime pravilno, se morda splača preveriti tudi, če se nisi zatipkal kje drugje, je morda kakšna pika namesto vejice ali obratno, morda kakšna spremenljivka z malo začetnico?
Možno je seveda tudi, da so tvoji pogoji prestrogi ali celo nemogoči (kot bi bila npr. zahteva,
da je N
enako kot N + 1
ali kaj podobno logično zlobnega).
Je morda na delu potencialno neskončna rekurzija? Kako se bo ustavila?
Morda pa je kriv tudi manjkajoč, neustrezen ali preprosto nekompatibilen (s splošnim primerom) robni pogoj?
''', 'empty_list_base_case': '''\V praznem seznamu boš težko našel najmanjši element. Kaj, če se tokrat ustaviš malo prej?
''', 'list_instead_of_elem_base_case': '''\Vrni element in ne seznam!
''', 'duplicates_not_covered': '''\Si pomislil, da so v seznamu lahko tudi duplikati?
''', 'args_not_instantiated': '''\Napaka, ki si jo dobil od prologa, pomeni, da ob uporabi aritmetike niso podane vse vrednosti spremenljivk.
Si morda pozabil, da konjunkcija veže močneje od disjunkcije oz. da je vsak prologov stavek (veja, pravilo) samostojen v smislu dosega spremenljivk? Morda je to problem. Pozorno poglej oba bloka kode (pred in za podpičjem), oziroma obe pravili.
''', 'unprotected_branch': '''\Zdi se mi, da si pozabil "zaščititi" eno izmed obeh vej. Obe veji (disjunkciji) potrebujeta pogoj, ne zanašaj se na to, da če je prišel v drugo vejo, potem prva ne velja. Velja OR in ne XOR. Zato jih moraš ti narediti ekskluzivne. Poskusi tole vprašanje in poglej vse možne rešitve, boš videl v čem je problem.
?- min([1,9,3,8,6], Min).
Si morda pozabil na eno izmed možnosti? Glava je lahko ali večja ali manjša od najmanjšega elementa v repu.
''', }