marcel@MERIDIAN.ADS.COM (Marcel Schoppers) (07/14/88)
I haven't kept up with attempts to clean up search control in Prolog, but let me throw out an idea and see what happens. Control in Prolog, when used around single predicates, comes in a few common flavors: 0 let P be satisfied any number of times with backtracking (no control) 1 let P be satisfied exactly once and report an error if it can't be satisfied (e.g. many built-ins and "low-level" user-defined procedures) 2 let P be satisfied zero times (not P) and very occasionally one needs 3 let P be satisfied at most once 4 see if P is satisfiable but don't bind any variables There is a fairly simple and neat way of capturing all these options with the following four operators: [ P P has >=1 solutions -- normal case ] -P P has 0 solutions (don't bind vars, no backtracking) +P P has >=1 solutions (don't bind vars, no backtracking) @X print error and fail unless X <one of the above> X! allow only 1 solution for X These operators combine to give the following control options: -P fail if there are any Ps (= not), don't bind vars, succeed once +P fail if there are no Ps, don't bind vars, succeed once @-P print error & fail if there are any Ps, don't bind vars, succeed once @+P print error & fail if there are no Ps, don't bind vars, succeed once P fail if there are no Ps, do bind vars, succeed N times @P print error & fail if there are no Ps, do bind vars, succeed N times P! fail if there are no Ps, do bind vars, succeed once @P! print error & fail if there are no Ps, do bind vars, succeed once So, with only four operators and at most two per term, we get the full range of ways to control how a goal can be satisfied. These are almost enough to replace the cut, but not quite. There are two types of control situations that these operators can't handle. Once of them is pred :- !, fail. and the other is when we exploit lexical clause ordering, as in call( (P,Q) ) :- !, call(P), call(Q). call( X ) :- ... % now can ignore the (P,Q) possibility In both these cases the cut controls not an individual goal, but affects the interpretation of the entire set of related clauses (naughty naughty). I'd like to hear why cut was designed as it was, given that yes, there is only one cut and it's strong enough to do everything we want, but it's not very readable and it's also not very intuitive to novices. Is it or is it not a good idea to replace cut with operators like those I defined above, provided that the other uses of cut can also be rationalized? marcel@ads.com