Re: Cyclical definition
Jan Wielemaker <[email protected]>
| Newsgroups | gmane.comp.ai.prolog.swi |
|---|---|
| Message-ID | <[email protected]> |
On 01/06/2014 08:42 AM, Daniel Lyons wrote: > > On Jan 6, 2014, at 12:09 AM, Anne Ogborn <[email protected]> wrote: > >> This question came up on ##prolog >> >> from a freshly started SWI-Prolog >> >> 1 ?- father(X) = X. >> X = father(X). >> >> 2 ?- >> >> I'm not sure what SWI-Prolog should do in this case? >> >> Defining father(7) seems to have no effect. >> >> the original poster said >> >> ] <Gal3rielol> Hi, in the new swipl, when I try father(X)=X, it gives me the answer X = father(X). But in the book LPN, it says that the answer should be like X = father(father(father(father(father(father(...)))))))))). > > SWI 6.2.2 has the odd behavior as well. GNU Prolog 1.4, on the other hand, does more-or-less what you expect: > > | ?- X = father(X). > > cannot display cyclic term for X > > yes > > >> I am baffled and feel fear in my heart, for Prolog eludes again. > > I’m glad I’m not the only one that happens to. It is mostly a matter of history, and most Prolog teaching material seems to be quite outdated :-( - Old and new Prolog systems typically do not implement the `occurs check', which implies that X = father(X) results in a `cyclic term'. SWI-Prolog has a flag occurs_check that you can set to `fail' or `error', which would be a good idea for a teaching environment. Thanks to Ulrich Neumerkel. - Faced with a cyclic term, many Prolog built-ins misbehave: e.g, (GNU Prolog): ?- X = f(X), Y = f(Y), X = Y. <loops> ?- X = X+1, Y is X. Segmentation fault - This behaviour is of course not very friendly and opens many routes for DoS attacks on servers, notably if they translate user queries into Prolog goals (for example the ClioPatria SPARQL engine). Therefore, quite a few systems implement decent handling of cyclic terms in all/many/some built-ins. So, the above gives (error could have been nicer :-() ?- X = f(X), Y = f(Y), X = Y. X = Y, Y = f(Y). ?- X = X+1, Y is X. ERROR: Type error: `expression' expected, found `@(S_1,[S_1=S_1+1])' (a cyclic) (cyclic term) (if you are interested: arithmetic evaluation keeps a recursive nesting count. If this reaches 1000, it will do a cycle test before continueing the evaluation). - SWI-Prolog also does that for top-level writing: if the terms are cyclic it will `factorize' the terms such that cycles are broken before printing. That is logically consistent behaviour. Cheers --- Jan