Page 1 of 1

Try/Catch block makes the cut useless:what is the rationale?

Posted: 16 Jul 2015 17:44
by Peter Muraya
Hi,
The commented code worked fine. I expanded it to trap runtime errors using a try/catch block and was surprised when the compiler complained that The predicate 'main::run/0', which is declared as 'procedure', is actually 'multi'. It is as if the try/catch block effectively removed the first cut so that I had to add the second one at the end to clear the error. Is this by design? If so, what is the logic behind this behavior?

Code: Select all

implement main     open core   clauses     /*      run() :-           try_test(2),!,           console::write("ok").       run() :-         console::write("fail").    */       run() :-         try           try_test(2),!, %This cut has now been rendered useless           console::write("ok")         catch _ do             stdio::write("error")         end try,!.  %This cut was added to clear the compiler error.     run() :-         console::write("fail").   class predicates      try_test:(integer) determ. clauses      try_test(X):-X>0.   end implement main   goal     console::runUtf8(main::run),     console::readchar()=_.

Posted: 16 Jul 2015 18:23
by Harrison Pratt
http://wiki.visual-prolog.com/index.php ... ch-finally

First Body is evaluated.
If Body fails or succeeds the whole try construction fails or succeeds, respectively. I.e. if Body does not terminate with an exception the try construction corresponds to evaluating Body.


So, your code reduces to this in the absence of an exception:

Code: Select all

run():- try_test(-2), !. run():- console::write("fail").
At least, that's how I understand it.

Posted: 16 Jul 2015 22:52
by Martin Meyer
I think the logic behind this behavior is, that in

Code: Select all

try         Body catch Var do         Handler end try
Body is a cut scope. I failed however to find a statement in the language reference saying so.

Many regards
Martin

Posted: 17 Jul 2015 5:04
by Peter Muraya
Thanks Harrison and Martin. This sheds some light. I was not aware of the idea of a cut scope beyond the traditional use in clauses such as in:-

Code: Select all

p():-nd,!,x(). p().
Perhaps the documentation should be expanded to read:-

...Several terms introduce cut scopes (see the respective terms: list comprehension, if-then-else, foreach, try-catch).....

Posted: 17 Jul 2015 13:47
by Thomas Linder Puls
There are no cut scopes in a try-catch construction.

Consider this schematic predicate:

Code: Select all

clauses     p(...) :-         try             Body         catch TraceId do             Handler         end try,         After.     p(...) :-         Otherwise.
There are two ways to reach After:
  • Body can succeed
  • Body terminates with an exception, and then Handler succeeds
So in both these cases it is possible to backtrack to Otherwise.

This backtracking can be prevented by a single cut in the After position, or by two individual cuts in the try-catch construction:

Code: Select all

clauses     p(...) :-         try             Body,             ! % Cut for the succeed case         catch TraceId do             Handler,             ! % Cut for the handler case         end try,         After.     p(...) :-         Otherwise.

Posted: 17 Jul 2015 17:20
by Martin Meyer
Aha ..that explains it. Thanx Thomas!

Regards
Martin

Posted: 20 Jul 2015 7:09
by Peter Muraya
Thank you Thomas; its very clear now.