[comp.lang.prolog] Having trouble with disjunction

F0O@psuvm.psu.edu (08/14/90)

    Last night, in PDC prolog I was trying to write the following predicate:

         gofirst(Player) :-
             random(RandNum),
             RandNum < 0.5, Player = computer ;
             RandNum >= 0.5, Player = opponent.

    When I tried to run the program, I got the message 'Free variables
not allowed here', at Player = opponent.
    Is this a quirk of PDC prolog, or don't I fully understand disjunction?

                                                         [Tim]

jgarland@kean.ucs.mun.ca (08/15/90)

In article <90226.091749F0O@psuvm.psu.edu>, F0O@psuvm.psu.edu writes:
The structure:

>          gofirst(Player) :-
>              random(RandNum),
>              RandNum < 0.5, Player = computer ;
>              RandNum >= 0.5, Player = opponent.
> 
>                        [Tim]


Nice idea, the problem is you're thinking in Pascal.  Disjunction 
works more like a case statement in PDC.  I.e. your structure is 
equivalent to:

   gofirst(Player) :- random(Ran),Ran < 0.5,Player=computer.
   gofirst(Player) :- Ran >= 0.5, Player=opponent.

Ran is indeed free.

Listing 1 clumsily implements your ideas using the cut

**************** Listing 1 ********************
predicates

 gofirst(symbol)
 
clauses

 gofirst(Player) :-
   random(Ran),Ran <= 0.5,
   !,
   Player = computer;
   
   Player = opponent.
   
goal

   gofirst(Player).
*************** end ****************

Listing 2 is more elegant if I may say and doesn't mimic Pascal
**************** Listing 2 ********************

predicates

   gofirst(symbol,integer)
   
clauses

   gofirst(computer,0).
   gofirst(opponent,1).
   
   
goal

   random(2,Ran),            %integer random number generator--fast
   gofirst(Player,Ran).


John Garland

Bitnet:  jgarland@mun
Internet: jgarland@kean.ucs.mun.ca

ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (08/15/90)

In article <90226.091749F0O@psuvm.psu.edu>, F0O@psuvm.psu.edu writes:
>          gofirst(Player) :-
>              random(RandNum),
>              RandNum < 0.5, Player = computer ;
>              RandNum >= 0.5, Player = opponent.
> 
>     When I tried to run the program, I got the message 'Free variables
> not allowed here', at Player = opponent.
>     Is this a quirk of PDC prolog, or don't I fully understand disjunction?

This is easily the best thing I have ever heard about PDC Prolog.
Your problem is that you have a terrible layout convention.
Let's put your code through a Prolog pretty-printer and see what comes out:

	gofirst(Player) :-
		(   random(RandNum),
		    RandNum < 0.5,
		    Player = computer
		;   RandNum >= 0.5,
		    Player = opponent
		).

See what's going on?
Use this indentation rule:  always write disjunctions as
		(   <disj1>
		;   <disj2>
		...
		;   <disjn>
		)
exactly like you'd write an Ada if statement, with "(" acting like "if",
"->" [when using it] acting like "then", ";" acting like "else if" or
"else", and ")" acting like "end if".  Following that rule, and writing
what you meant, we get

	gofirst(Player) :-
		random(RandNum),
		(   RandNum < 0.5,
		    Player = computer
		;   RandNum >= 0.5,
		    Player = opponent
		).

-- 
The taxonomy of Pleistocene equids is in a state of confusion.

stefan@hpbbi4.BBN.HP.COM (#Stefan Bachert) (08/15/90)

/ hpbbi4:comp.lang.prolog / F0O@psuvm.psu.edu /  3:17 pm  Aug 14, 1990 /

Watch the precedence. I added brackets to show you what you
told your prolog.


         gofirst(Player) :-
         (   random(RandNum),
             RandNum < 0.5, Player = computer );
         (   RandNum >= 0.5, Player = opponent).

I think you intended the following 

         gofirst(Player) :-
             random(RandNum),
            (RandNum < 0.5, Player = computer ;
             RandNum >= 0.5, Player = opponent).


Stefan