What are the pros and cons of using manual list iteration vs recursion through fail

前端 未结 3 1843
灰色年华
灰色年华 2020-12-07 01:53

I come up against this all the time, and I\'m never sure which way to attack it. Below are two methods for processing some season facts.

What I\'m trying to work out

3条回答
  •  情歌与酒
    2020-12-07 02:20

    Lets look at your example. It is very simple, so we will imagine it being more complex. However, it seems you take for granted that side effects are essential. Let me question that a bit:

    In your example you have made a very interesting discovery: The names of all seasons are of same length. What an earth-shattering insight! But wait, is it really true? The most straight-forward way to verify this, is:

    ?- season(S), atom_length(S,L).
    S = spring,
    L = 6 ;
    S = summer,
    L = 6 ;
    S = autumn,
    L = 6 ;
    S = winter,
    L = 6.
    

    No need for findall/3, no need for write/1.

    For a larger number of answers, visual inspection is not practical. Imagine 400 seasons. But we can verify this with:

    ?- season(S), atom_length(S,L), dif(L,6).
    false.
    

    So we now know for sure that there is no season of a different length.

    That is my very first answer to your question:

    As long as you can, use the toplevel shell and not your own side effecting procedures! Stretch things a little bit further to avoid side-effects altogether. This is the best way to avoid failure driven loops right from the beginning.

    There are more reasons why sticking to the toplevel shell is a good idea:

    • If your programs can be easily queried on the toplevel, it will be trivial to add test cases for them.

    • The toplevel shell is used by many other users and therefore is very well tested. Your own writing is often flawed and untested. Think of constraints. Think of writing floats. Will you use write/1 for floats too? What is the right way to write floats such that they can be read back accurately? There is a way to do this in iso-prolog. Here is the answer:

    In ISO, writeq/1,2, write_canonical/1,2, write_term/2,3 with option quoted(true) guarantee that floats can be read back accurately. That is, they are the same w.r.t. (==)/2

    • The toplevel shell shows you valid Prolog text. In fact, the answer itself is a query! It can be pasted back into the toplevel - only to get back the very same answer. In this manner you will learn the more exotic but unavoidable details of Prolog, like quoting, escaping and bracketing. It is practically impossible to learn the syntax otherwise, since Prolog parsers are often extremely permissive.

    • Your program will be most probably more accessible to declarative reasoning.

    Very likely, your two procedures methodone and methodtwo are incorrect: You forgot a newline after writing Done. So methodone, methodone contains a garbled line. How to test that easily?

    But lets look a little bit further into your program. What is so typical for failure driven loops is that they start innocently as something doing "only" side effects but sooner or later they tend to attract more semantic parts as well. In your case, atom_length/2 is hidden down in the failure driven loop completely inaccessible to testing or reasoning.

    Efficiency considerations

    Prolog systems often implement failure by deallocating a stack. Therefore, failure driven loops will not require a garbage collector. That's why people believe that failure driven loops are efficient. However, this is not necessarily the case. For a goal like findall(A, season(A), As) every answer for A is copied into some space. This is a trivial operation for something like atoms but imagine a bigger term. Say:

    blam([]).
    blam([L|L]) :- blam(L).
    
    bigterm(L) :- length(L,64), blam(L).
    

    In many systems, findall/3 or assertz/1 for this big term will freeze the system.

    Also, systems like SWI, YAP, SICStus do have quite sophisticated garbage collectors. And using fewer failure driven loops will help to improve those systems even further, since this creates a demand for more sophisticated techniques.

提交回复
热议问题