Discussions related to Visual Prolog
dcgreenwood
Posts: 24
Joined: 16 Jan 2021 1:33

Predicate called from menu must be a procedure (?)?

Unread post by dcgreenwood »

I have a predicate runExperiment() being called from a menu. It seems that a predicate called from a menu item must be a procedure - anything else causes an error that I have not been able to resolve? Is this so?

The predicates that start my program are
(runExperiment is declared in main.cl as
predicate
runExperiment: ().
)

Code: Select all

class predicates     startExperiment : ().     checkIfExperimentOver : (flag Over [out]) determ.     advanceCounter : () nondeterm.   clauses     runExperiment() :-         startExperiment().       startExperiment() :-         assert(turnCounter(0)),         assert(objectiveStatus(b2, no, "anonymous")),         !,         checkIfExperimentOver(Over),         if Over = no then             executeTurn(),             startExperiment()         else             stdio::write("\nExperiment Concluded.\n\n")         end if.         checkIfExperimentOver(Over) :-         stdio::write("Checking to see if Experiment is Over.\n"),         !,         turnCounter(Counter),         if Counter > 100 then             % or Obj = yes then             Over = yes         else             Over = no         end if,         !.     checkIfExperimentOver(yes).
With this, Build gives an error message that startExperiment must be determ. But if I change it to determ, I get an error message that runExperiment must be determ. If I change that, I get an error message that the Task Window predicate that calls runExperiment must be determ, and if I change that I get an error message pointing into the gui code that I don't understand.

What do I need to change in order to ensure that runExperiment() is a procedure? Or am I wrong, and the predicate called by the menu item does not need to be a procedure?
Harrison Pratt
VIP Member
Posts: 439
Joined: 5 Nov 2000 0:01

Re: Predicate called from menu must be a procedure (?)?

Unread post by Harrison Pratt »

One way is the catch any failure of startExperiment() so it does not fail, although that may not be what you want to do:

Code: Select all

clauses     runExperiment() :-         startExperiment(),         !         or         succeed.
or you can catch failure in runExperiment(), although that may not be what you want to do either:

Code: Select all

clauses     runExperiment() :-         startExperiment(),         !.     runExperiment().
If you want to handle any experiment failure ("Something went wrong!") condition, then you can also handle the failure in your menu clause, something like this:

Code: Select all

onMyMenuEvent(_Source,_MenuTag):-     if runExperiment() then         succeed     else         stdio::write("\nYikes!  My experiment failed.")     end if.
You should notice that I have shown 3 different approaches to handling failure:
  • Use of logical or. Note that this may require use of a cut (!).
  • Use of additional clauses
  • Use of if ... then ... else ... end if.
dcgreenwood
Posts: 24
Joined: 16 Jan 2021 1:33

Re: Predicate called from menu must be a procedure (?)?

Unread post by dcgreenwood »

Thanks. The first option was perfect. I had not seen the use of OR this way before, I'm sure I will use one or all of these sequences again.
User avatar
Thomas Linder Puls
VIP Member
Posts: 1398
Joined: 28 Feb 2000 0:01

Re: Predicate called from menu must be a procedure (?)?

Unread post by Thomas Linder Puls »

You can also use orelse:

Code: Select all

clauses      runExperiment() :-          startExperiment() orelse succeed.
Regards Thomas Linder Puls
PDC
Post Reply