/* CUT. Three common uses. */ /* 1) Confirming the choice of a rule: */ sum_to(N,1) :- N=<1,!. sum_to(N,R) :- N1 is N-1, sum_to(N1,R1), R is R1 + N. sum_toWrong(N,1) :- N=<1. sum_toWrong(N,R) :- N1 is N-1, sum_toWrong(N1,R1), R is R1 + N. /* Testrun: | ?- sum_to(2,R). R = 3 yes | ?- sum_toWrong(2,R). R = 3 ? ; R = 4 ? ; R = 4 ? ; R = 3 ? ; R = 1 ? ; R = -2 ? ; R = -6 ? ; R = -11 ? */ /* 2) Forced failure, don't try further alternatives (cut-fail): */ income(peter,400000). foreigner(peter). average_taxpayerWrong(X) :- foreigner(X), fail. average_taxpayerWrong(X) :- income(X,I), I < 500000. average_taxpayer(X) :- foreigner(X), !, fail. average_taxpayer(X) :- income(X,I), I < 500000. /* Testrun: | ?- average_taxpayerWrong(peter). yes | ?- average_taxpayer(peter). no */ /* Negation as failure (built-in in gprolog as prefix operator \+) */ not(X) :- call(X), !, fail. not(X). /* 3) Terminating generate-and-test code after first solution found */ /* Divide N1 by N2 */ divide(N1, N2, Result) :- is_integer(Result), div_test(N1, N2, Result), !. /* Generate all integers */ is_integer(1). is_integer(X) :- is_integer(Y), X is Y+1. /* Test for N1/N2 = D */ div_test(N1,N2,D) :- P1 is N2*D, P2 is N2*(D+1), P1 =< N1, P2 > N1.