3

The following code, as expected, outputs 123 because of backtracking:

between(1,3,X), write(X), false.

This one with the cut outputs 1, also as expected:

between(1,3,X), write(X), !, false.

But this one outputs 123 surprisingly:

between(1,3,X), write(X), not(!).

not(!) evaluates to false so in one way it makes sense that it backtracks but at the same time it should have cut and therefore have no other possibilites to explore.

The same behaviour happens with \+ instead of not/1.

Why is the cut not having any side effect when negated? For example write/1 in a not has the same side effect as when it's not in one.

false
  • 10,264
  • 13
  • 101
  • 209
Fatalize
  • 3,513
  • 15
  • 25

1 Answers1

2

(\+)/1 it's a metacall builtin, and (citing the !/0 docs)

Meta calling is opaque to the cut.

The examples, specially t4, illustrate the operational semantic

CapelliC
  • 59,646
  • 5
  • 47
  • 90
  • 2
    Sorry, but example t4 is **incorrect**. There is no predicate `(\+)/3`. – false Sep 11 '15 at 10:27
  • 2
    Contrary to the documentation of SWI, `(\+)/1` is handled (incorrectly) like a control construct - so it is not handled like a built-in. As an example, consider: `call((fail,\+1))` which must fail, but in SWI it is an error. This is non-conforming behavior specific to SWI. – false Sep 11 '15 at 10:31