Discussions related to Visual Prolog
Peter Muraya
VIP Member
Posts: 147
Joined: 5 Dec 2012 7:29

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

Unread post 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()=_.
Mutall Data Management Technical Support
Harrison Pratt
VIP Member
Posts: 439
Joined: 5 Nov 2000 0:01

Unread post 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.
Martin Meyer
VIP Member
Posts: 328
Joined: 14 Nov 2002 0:01

Unread post 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
Peter Muraya
VIP Member
Posts: 147
Joined: 5 Dec 2012 7:29

Unread post 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).....
Mutall Data Management Technical Support
User avatar
Thomas Linder Puls
VIP Member
Posts: 1398
Joined: 28 Feb 2000 0:01

Unread post 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.
Last edited by Thomas Linder Puls on 17 Jul 2015 20:07, edited 1 time in total.
Regards Thomas Linder Puls
PDC
Martin Meyer
VIP Member
Posts: 328
Joined: 14 Nov 2002 0:01

Unread post by Martin Meyer »

Aha ..that explains it. Thanx Thomas!

Regards
Martin
Peter Muraya
VIP Member
Posts: 147
Joined: 5 Dec 2012 7:29

Unread post by Peter Muraya »

Thank you Thomas; its very clear now.
Mutall Data Management Technical Support
Post Reply