/*			APPENDIX C
      Section C.5  A Situation Calculus Representation of a FACTORY Example
*/
:- set_flag(all_dynamic, on). 
:- dynamic(proc/2).
:- dynamic(skilledLabourPresent/1).
:- dynamic(hasSprayGun/1).
:- dynamic(hasGlue/1).
:- dynamic(hasBolts/1).
:- pragma(debug).

/* This file is  "myfactory6"; version 6 of SPUDD test factory examples.
		35 FLUENTS (grounded)

% The first 17 variables are mentioned in factory.dat example
t : Type_Needed       A high (true) or low (false) quality job is required
c : Connected         Objects a and b are connected
cw : Connected_Well   Objects a and b are well connnected
ap : A_painted        Object a is painted
apw : A_painted_well  Object a is well painted
bp : B_painted        Object b is painted
bpw : B_painted       Object b is well painted
ash : A_shaped        Object a is shaped
bsh : B_shaped        Object b is shaped
asm : A_smoothed      Object a is smoothed
bsm : B_smoothed      Object b is smoothed
adr : A_drilled       Object a is drilled
bdr : B_drilled       Object b is drilled
bo : Bolts            The robot has bolts
gl : Glue             The robot has glue
sg : Spray_Gun        The robot has a spray gun
sl : Skilled_Labour   There is skilled labour present

% The following 2 variables are mentioned in factory0.dat and
% all subsequent examples
cl : Clamps            The robot has clamps
dr : Drill             The robot has a drill

% The following 2 variables are mentioned in factory1.dat and
% all subsequent examples. Thus, factory1.dat has 21 boolean variables
mo : Mounting           The robot has a mounting device
br : Brushes            The robot has brushes

% The following 7 variables are mentioned in factory4.dat and
% all subsequent examples. Thus, factory4.dat has 28 boolean variables
la : Laquer              Laquer is available
aw : arc-welder          The robot has an arc-welder
sw : spot welder         The robot has a spot-welder
swl : arc-welder labour  Skilled labour for the arc-welder is available
bit : bit                The robot has bits for the drill
awe : arc-welds          The robot has welding materials for the arc-welder
swe : spot-welds         The robot has welding materials for the spot-welder

% The following 7 variables are mentioned in factory6.dat example. The first
% two variables "cac" and "cbc" occur in factory5.dat and all
% remaining 5 variables occur only in the last example factory6.dat 
% Thus, factory6.dat has 35 boolean variables and the size of
% the state space is 2^35 (i.e., approximately 3.4x10^10) states.
cac : CA_Connected        Objects C and A are connected 
cbc : CB_Connected        Objects C and B are connected
cp : C_painted            Object c is painted
cpw : C_painted_well      Object c is well painted
csh : C_shaped            Object c is shaped
csm : C_smoothed          Object c is smoothed
cdr : C_drilled           Object c is drilled

		14 ACTIONS (grounded)
% These 14 actions are used in all factory related examples
Shape object a
Shape object b
Drill object a
Drill object b
Dip (paint) object a
Dip (paint) object b
Spray (paint) object a
Spray (paint) object b
Hand-paint object a
Hand-paint object b
Bolt two objects A and B together
Glue two objects together
Polish object a
Polish object b

% The following action is used in all examples starting from factory3.dat
Weld objects A and B

% factory6.dat example has additional 8 actions (23 actions in total)
% The first two actions occur in factory5.dat example and all remaining
% 7 actions are allowed only in the factory6.dat example.
% Because the situation calculus representation is using action terms 
% weld(x,y) and glue(x,y), where the variables x and y vary over objects
% {a,b,c} allowed in the factory domain, the axiomatization allows
% several additional actions (e.g., weld(a,c), weld(b,c), glue(a,c), 
% glue(b,c)) that are not  allowed in the factory6.dat example.
Bolt objects A and C together
Bolt objects B and C together
Shape object c
Drill object c
Dip (paint) object c
Spray (paint) object c
Hand-paint object c
Polish object c
*/
		/* Nondeterministic actions */

/* The action "spray(X)" might have four different outcomes:
   a part becomes painted and well painted - nature's action is "spraySW",
a part becomes painted but not well painted - nature's action is "spraySnW",
a part remains unpainted, but is well painted - nature's action is "sprayFW",
a part remains unpainted and not well painted - nature's action is "sprayFnW".
   According to the probabilities of transitions between states choosen for
   the factory0 example in the SPUDD demo version, the probability of becoming 
 painted is 0.9 (a part remains unpainted with 0.1 probability). The probability 
   of becoming well painted is 0.44 (a part will not be well painted with 
   the probability 0.56)
*/
nondetActions(spray(X), S, [spraySW(X), spraySnW(X), sprayFW(X), sprayFnW(X)]).

nondetActions(shape(X), S, [shapeS(X), shapeF(X)]).

nondetActions(handPaint(X), S, [handPaintS(X), handPaintF(X)]).

nondetActions(polish(X), S, [polishS(X), polishF(X)]).

nondetActions(drill(X), S, [drillS(X), drillF(X)]).

nondetActions(weld(X,Y), S, [weldS(X,Y), weldF(X,Y)]).


        /* Identification conditions for stochastic actions */

senseCondition(spraySW(Obj), Phi) :- Phi=( painted(Obj) & paintedWell(Obj) ).
senseCondition(spraySnW(Obj), Phi) :- Phi=( painted(Obj) & (-paintedWell(Obj)) ).
senseCondition(sprayFW(Obj), Phi) :- Phi=( (-painted(Obj)) & paintedWell(Obj) ).
senseCondition(sprayFnW(Obj),Phi) :- Phi=((-painted(Obj)) & (-paintedWell(Obj))).

senseCondition(shapeS(Obj), Phi) :- Phi=shaped(Obj) .
senseCondition(shapeF(Obj), Phi) :- Phi=(-shaped(Obj)) .

senseCondition(handPaintS(X), Phi) :-  Phi=paintedWell(X).
senseCondition(handPaintF(X), Phi) :-  Phi=(-paintedWell(X)).

senseCondition(polishS(Obj), Phi) :- Phi=smoothed(Obj) .
senseCondition(polishF(Obj), Phi) :- Phi=(-smoothed(Obj)) .

senseCondition(drillS(Obj), Phi) :- Phi=drilled(Obj) .
senseCondition(drillF(Obj), Phi) :- Phi=(-drilled(Obj)) .

senseCondition(weldS(Obj1,Obj2), Phi) :- Phi=connectedWell(Obj1,Obj2) .
senseCondition(weldF(Obj1,Obj2), Phi) :- Phi=(-connectedWell(Obj1,Obj2)) .

    
                          /* Probabilities */

prob(spraySW(X),Pr,S) :-  hasMountingDevice(S), ( Pr is 0.9*0.44 ) .
prob(spraySnW(X),Pr,S) :- hasMountingDevice(S), ( Pr is 0.9*0.56 ) .
prob(sprayFW(X),Pr,S) :-  hasMountingDevice(S), ( Pr is 0.1*0.44 ) .
prob(sprayFnW(X),Pr,S) :- hasMountingDevice(S), ( Pr is 0.1*0.56 ) .

prob(spraySW(X),0,S) :-  not hasMountingDevice(S).
prob(spraySnW(X),1,S) :- not hasMountingDevice(S).
prob(sprayFW(X),0,S) :-  not hasMountingDevice(S).
prob(sprayFnW(X),0,S) :- not hasMountingDevice(S).

prob(shapeS(X),Pr,S) :-  ( Pr is 0.8 ) .
prob(shapeF(X),PrF,S) :- prob(shapeS(X),PrS, S),  (PrF is 1.0 - PrS ) .

prob(handPaintS(X),Pr,S) :-  ( Pr is 0.8 ) .
prob(handPaintF(X),PrF,S) :- prob(handPaintS(X),PrS, S),  (PrF is 1.0 - PrS ) .

prob(polishS(X),Pr,S) :-  ( Pr is 0.8 ) .
prob(polishF(X),PrF,S) :-  prob(polishS(X),PrS, S),  (PrF is 1.0 - PrS ) .

prob(drillS(X),Pr,S) :-  ( Pr is 0.8 ) .
prob(drillF(X),PrF,S) :-  prob(drillS(X),PrS, S),  (PrF is 1.0 - PrS ) .

prob(weldS(X,Y),Pr,S) :- ( Pr is 0.9 ) .
prob(weldF(X,Y),PrF,S) :- prob(weldS(X,Y),PrS, S), (PrF is 1.0 - PrS ) .


                		/* Precondition axioms */

poss(spraySW(X),S) :- object(X), hasSprayGun(S).
poss(spraySnW(X),S) :- object(X), hasSprayGun(S).
poss(sprayFW(X),S) :- object(X), hasSprayGun(S).
poss(sprayFnW(X),S) :- object(X), hasSprayGun(S).

poss(shapeS(X),S) :- object(X), not (object(Y), not X=Y, connected(X,Y,S)),
                    not (object(Y), not X=Y, connectedWell(X,Y,S)).

poss(shapeF(X),S) :- object(X), not (object(Y), not X=Y, connected(X,Y,S)),
                    not (object(Y), not X=Y, connectedWell(X,Y,S)).

poss(handPaintS(X),S) :- object(X),  hasBrushes(S).
poss(handPaintF(X),S) :- object(X),  hasBrushes(S).

poss(polishS(X),S) :- object(X).
poss(polishF(X),S) :- object(X).

poss(drillS(X),S) :- object(X).
poss(drillF(X),S) :- object(X).

poss(weldS(X,Y),S) :- object(X), object(Y), hasSkilledWelder(S).
poss(weldF(X,Y),S) :- object(X), object(Y), hasSkilledWelder(S).

poss(dip(X),S) :- object(X).

poss(bolt(X,Y),S) :-  drilled(X,S), drilled(Y,S), not X=Y, hasBolts(S).

poss(glue(X,Y),S) :- object(X), object(Y), not X=Y, hasGlue(S), hasClamps(S).


		            /*   Successor state axioms */

typeNeeded(JobQuality,do(A,S)) :- typeNeeded(JobQuality,S).
/* In the initial situation s0, arguments can be typeNeeded(highQuality,s0)
   or  typeNeeded(lowQuality,s0)  */

skilledLabourPresent(do(A,S)) :- skilledLabourPresent(S).
hasSprayGun(do(A,S)) :- hasSprayGun(S).
hasGlue(do(A,S)) :- hasGlue(S).
hasBolts(do(A,S)) :- hasBolts(S).

/* hasClamps(S) and hasDrill(S) are introduced in factory0.dat */
hasClamps(do(A,S)) :- hasClamps(S).
hasDrill(do(A,S)) :- hasDrill(S).

/* hasMountingDevice(S) and hasBrushes(S) are introduced in factory1.dat */
hasMountingDevice(do(A,S)) :- hasMountingDevice(S).
hasBrushes(do(A,S)) :- hasBrushes(S).

/* hasLaquer(S) is the only one new fluent in factory2.dat: this fluent is
   not mentioned in any other s.-s. or precondition axiom */
hasLaquer(do(A,S)) :- hasLaquer(S).

/*
hasSkilledWelder(S),hasArcWelder(S), hasSpotWelder(S) introduced in factory3.dat */
hasArcWelder(do(A,S)) :- hasArcWelder(S).
hasSpotWelder(do(A,S)) :- hasSpotWelder(S).
hasSkilledWelder(do(A,S)) :- hasSkilledWelder(S).

/*hasBits(S), hasArcMaterials(S), hasSpotMaterials(S) introduced in factory4.dat*/
hasArcMaterials(do(A,S)) :- hasArcMaterials(S).
hasSpotMaterials(do(A,S)) :- hasSpotMaterials(S).
hasBits(do(A,S)) :- hasBits(S).


connected(X,Y,do(A,S)) :- A=bolt(X,Y).
connected(X,Y,do(A,S)) :- A=glue(X,Y).

connected(X,Y,do(A,S)) :- A=bolt(Y,X).
connected(X,Y,do(A,S)) :- A=glue(Y,X).

connected(X,Y,do(A,S)) :- 
       (A=weldS(X,Y) ; (A=weldS(Y,X) ; (A=weldF(X,Y) ; A=weldF(Y,X)))) ,
	   hasArcWelder(S), hasArcMaterials(S).

connected(X,Y,do(A,S)) :- 
       not hasArcWelder(S), hasSpotWelder(S), hasSpotMaterials(S), 
       ( A=weldS(X,Y) ; A=weldS(Y,X) ).

connected(X,Y,do(A,S)) :- connected(X,Y,S),
        not A=shapeS(X), not A=shapeF(X), not A=shapeS(Y), not A=shapeF(Y).

connectedWell(X,Y,do(A,S)) :- A=bolt(X,Y).
connectedWell(X,Y,do(A,S)) :- A=bolt(Y,X).

connectedWell(X,Y,do(A,S)) :- 
       (A=weldS(X,Y) ; (A=weldS(Y,X) ; (A=weldF(X,Y) ; A=weldF(Y,X)))) ,
	   ( connected(X,Y,S) -> hasArcMaterials(S) ;
	     hasArcWelder(S), hasArcMaterials(S) ).
/*
connectedWell(X,Y,do(A,S)) :- 
       (A=weldS(X,Y) ; (A=weldS(Y,X) ; (A=weldF(X,Y) ; A=weldF(Y,X)))) ,
	   hasArcWelder(S), hasArcMaterials(S), not connected(X,Y,S).  
*/
connectedWell(X,Y,do(A,S)) :- connectedWell(X,Y,S), 
       not A=shapeS(X), not A=shapeF(X), not A=shapeS(Y), not A=shapeF(Y),
       not (A=weldS(X,Y), connected(X,Y,S)),
       not (A=weldF(X,Y), connected(X,Y,S)),
       not (A=weldS(Y,X), connected(X,Y,S)), 
       not (A=weldF(Y,X), connected(X,Y,S)).

painted(X,do(A,S)) :- A=dip(X), smoothed(X,S).
painted(X,do(A,S)) :- A=spraySW(X), smoothed(X,S).
painted(X,do(A,S)) :- A=spraySnW(X), smoothed(X,S).
painted(X,do(A,S)) :- A=handPaintS(X), smoothed(X,S).
painted(X,do(A,S)) :- A=handPaintF(X), smoothed(X,S).

painted(X,do(A,S)) :- painted(X,S), 
                not A=shapeS(X),  not A=shapeF(X),
                not A=polishS(X),  not A=polishF(X),
                not A=drillS(X),  not A=drillF(X),
                not (object(Y), not X=Y, A=shapeS(Y), connected(X,Y,S)), 
                not (object(Y), not X=Y, A=shapeF(Y), connected(X,Y,S)), 
                not (object(Y), not X=Y, A=drillS(Y), connected(X,Y,S)),       
                not (object(Y), not X=Y, A=drillF(Y), connected(X,Y,S)),
                not (object(Y), not X=Y, A=polishS(Y), connected(X,Y,S)),       
                not (object(Y), not X=Y, A=polishF(Y), connected(X,Y,S)),
                not (object(Y), not X=Y, A=dip(Y), connected(X,Y,S)),
				not sprayConnected(X,A,S).

sprayConnected(X,A,S) :- object(Y), not X=Y, connected(X,Y,S),
       ( A=spraySW(Y) ; ( A=spraySnW(Y) ; ( A=sprayFW(Y) ; A=sprayFnW(Y)) ) ).

paintedWell(X,do(A,S)) :- A=spraySW(X), smoothed(X,S).
paintedWell(X,do(A,S)) :- A=sprayFW(X), smoothed(X,S).
paintedWell(X,do(A,S)) :- A=handPaintS(X), 
                   skilledLabourPresent(S), smoothed(X,S).

paintedWell(X,do(A,S)) :- paintedWell(X,S), 
                not A=shapeS(X), not A=shapeF(X),
                not A=polishS(X),  not A=polishF(X),
                not A=drillS(X),  not A=drillF(X),
                not A=dip(X),
                not (object(Y), not X=Y, A=shapeS(Y), connected(X,Y,S)),
                not (object(Y), not X=Y, A=shapeF(Y), connected(X,Y,S)),
                not (object(Y), not X=Y, A=drillS(Y), connected(X,Y,S)),       
                not (object(Y), not X=Y, A=drillF(Y), connected(X,Y,S)),
                not (object(Y), not X=Y, A=polishS(Y), connected(X,Y,S)),       
                not (object(Y), not X=Y, A=polishF(Y), connected(X,Y,S)),
                not (object(Y), not X=Y, A=dip(Y), connected(X,Y,S) ),
                not sprayConnected(X,A,S).

shaped(X,do(A,S)) :- A=shapeS(X), not (object(Y), not X=Y, connected(X,Y,S)).

shaped(X,do(A,S)) :- shaped(X,S), 
        not (object(Y), not X=Y, A=drillS(X), connected(X,Y,S)),       
        not (object(Y), not X=Y, A=drillF(X), connected(X,Y,S)),
        not (object(Y), not X=Y, A=drillS(Y), connected(X,Y,S)),       
        not (object(Y), not X=Y, A=drillF(Y), connected(X,Y,S)),  
        not (object(Y), not X=Y, A=shapeS(X), connected(X,Y,S)),
        not (object(Y), not X=Y, A=shapeF(X), connected(X,Y,S)),
        not (object(Y), not X=Y, A=shapeS(Y), connected(X,Y,S)),
        not (object(Y), not X=Y, A=shapeF(Y), connected(X,Y,S)).

smoothed(X,do(A,S)) :- A=polishS(X), shaped(X,S).

smoothed(X,do(A,S)) :- smoothed(X,S), not A=shapeS(X), not A=shapeF(X),
          not A=drillS(X),  not A=drillF(X),
          not (object(Y), not X=Y, A=shapeS(Y), connected(X,Y,S)),
	  not (object(Y), not X=Y, A=shapeF(Y), connected(X,Y,S)),
	  not (object(Y), not X=Y, A=drillS(Y), connected(X,Y,S)),
	  not (object(Y), not X=Y, A=drillF(Y), connected(X,Y,S)).

drilled(X,do(A,S)) :- A=drillS(X), hasDrill(S), hasBits(S), 
          not (object(Y), not X=Y, connected(X,Y,S)).

drilled(X,do(A,S)) :- drilled(X,S), 
	   not (object(Y), not X=Y, A=drillS(X), connected(X,Y,S)),
	   not (object(Y), not X=Y, A=drillF(X), connected(X,Y,S)),
	   not (object(Y), not X=Y, A=drillS(Y), connected(X,Y,S)),
	   not (object(Y), not X=Y, A=drillF(Y), connected(X,Y,S)).


				/* Reward function */

reward(R, s0) :- R is 0.
 
/* high quality */

reward(R,S) :- typeNeeded(highQuality,S), 
               not connected(a,b,S),  R is 0.

reward(R,S) :- typeNeeded(highQuality,S),  
               connected(a,b,S), not connected(a,c,S), R is 0.
	
reward(R,S) :- typeNeeded(highQuality,S), 
               connected(a,b,S), connected(a,c,S), 
               not (connected(b,c,S), connectedWell(a,b,S)), 
               R is 0.

reward(R,S) :- typeNeeded(highQuality,S), 
            connected(a,b,S), connectedWell(a,b,S), 
            connected(a,c,S), connected(b,c,S),
            (not painted(a,S), R is 1 ;
             painted(a,S), 
               ( not paintedWell(a,S), R is 1 ;
                 paintedWell(a,S), 
                   ( not painted(b,S), R is 2 ;
                     painted(b,S), 
                        ( not paintedWell(b,S), R is 4 ;
                          paintedWell(b,S),
                             ( not painted(c,S), R is 6 ;
                               painted(c,S), 
                                  (not paintedWell(c,S), R is 8 ;
                                   paintedWell(c,S), R is 10
                                   )
                              )
                         )
                    )
                )
             ).
/*
reward(R,S) :- typeNeeded(highQuality,S),  
               connected(a,b,S), connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
               not painted(a,S), R is 1.

reward(R,S) :- typeNeeded(highQuality,S),  
               connected(a,b,S), connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
               painted(a,S), not paintedWell(a,S), R is 1.

reward(R,S) :- typeNeeded(highQuality,S),  
               connected(a,b,S), connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
               painted(a,S), paintedWell(a,S), 
               not painted(b,S), R is 2.

reward(R,S) :- typeNeeded(highQuality,S),  
               connected(a,b,S), connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
               painted(a,S), paintedWell(a,S), 
               painted(b,S), not paintedWell(b,S),  R is 4.

reward(R,S) :- typeNeeded(highQuality,S),
               connected(a,b,S), connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
               painted(a,S), paintedWell(a,S), 
               painted(b,S), paintedWell(b,S), not painted(c,S), R is 6.

reward(R,S) :- typeNeeded(highQuality,S),  
               connected(a,b,S), connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
               painted(a,S), paintedWell(a,S), 
               painted(b,S), paintedWell(b,S), 
               painted(c,S), not paintedWell(c,S), R is 8.

reward(R,S) :- typeNeeded(highQuality,S),  
               connected(a,b,S), connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
               painted(a,S), paintedWell(a,S), 
               painted(b,S), paintedWell(b,S), 
               painted(c,S), paintedWell(c,S), R is 10.
*/
/* low quality */
reward(R,S) :- typeNeeded(lowQuality,S), 
               not connected(a,b,S), R is 0.

reward(R,S) :- typeNeeded(lowQuality,S), 
               connected(a,b,S), not connected(a,c,S), R is 0.

reward(R,S) :- typeNeeded(lowQuality,S), 
               connected(a,b,S), connected(a,c,S), 
               not connected(b,c,S), R is 0.

%---------------------------------------------------------
reward(R,S) :- typeNeeded(lowQuality,S),  
               connected(a,b,S), not connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
			   not painted(a,S),          % Part "a" is not painted 
			   not painted(b,S), R is 2.

reward(R,S) :- typeNeeded(lowQuality,S), 
               connected(a,b,S), not connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
			   not painted(a,S),          % Part "a" is not painted
			   painted(b,S), not paintedWell(b,S), R is 3.

reward(R,S) :- typeNeeded(lowQuality,S),  
               connected(a,b,S), not connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
			   not painted(a,S),          % Part "a" is not painted
               painted(b,S), paintedWell(b,S),        % "b" is painted and well
               not painted(c,S), R is 3.

reward(R,S) :- typeNeeded(lowQuality,S),  
               connected(a,b,S), not connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
			   not painted(a,S),          % Part "a" is not painted
               painted(b,S), paintedWell(b,S),        % "b" is painted and well
               painted(c,S), not paintedWell(c,S), R is 4.

reward(R,S) :- typeNeeded(lowQuality,S),  
               connected(a,b,S), not connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
			   not painted(a,S),          % Part "a" is not painted
               painted(b,S), paintedWell(b,S),        % "b" is painted and well
               painted(c,S), paintedWell(c,S), R is 3.
%---------------------------------------------------------
reward(R,S) :- typeNeeded(lowQuality,S),  
               connected(a,b,S), not connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
               painted(a,S), not paintedWell(a,S),  %"a" is painted, but not well
			   not painted(b,S), R is 4.

reward(R,S) :- typeNeeded(lowQuality,S),  
               connected(a,b,S), not connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
               painted(a,S), not paintedWell(a,S),  %"a" is painted, but not well
			   painted(b,S), not paintedWell(b,S), R is 5.

reward(R,S) :- typeNeeded(lowQuality,S), 
               connected(a,b,S), not connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
               painted(a,S), not paintedWell(a,S), % "a" is painted, but not well
               painted(b,S), paintedWell(b,S),     % "b" is painted and well
               not painted(c,S), R is 4.

reward(R,S) :- typeNeeded(lowQuality,S), 
               connected(a,b,S), not connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
               painted(a,S), not paintedWell(a,S), % "a" is painted, but not well
               painted(b,S), paintedWell(b,S),     % "b" is painted and well
               painted(c,S), not paintedWell(c,S),
               R is 5.

reward(R,S) :- typeNeeded(lowQuality,S), 
               connected(a,b,S), not connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
               painted(a,S), not paintedWell(a,S), % "a" is painted, but not well
               painted(b,S), paintedWell(b,S),     % "b" is painted and well
               painted(c,S), paintedWell(c,S),
               R is 4.
%---------------------------------------------------------
reward(R,S) :- typeNeeded(lowQuality,S), 
               connected(a,b,S), not connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
               painted(a,S), paintedWell(a,S),  % Part "a" is painted and well
               not painted(b,S),                % "b" is not painted 
               R is 3.

reward(R,S) :- typeNeeded(lowQuality,S), 
               connected(a,b,S), not connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
               painted(a,S), paintedWell(a,S),     % Part "a" is painted and well
               painted(b,S), not paintedWell(b,S), % "b" is painted, but not well
               R is 4.

reward(R,S) :- typeNeeded(lowQuality,S), 
               connected(a,b,S), not connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
               painted(a,S), paintedWell(a,S),  % Part "a" is painted and well
               painted(b,S), paintedWell(b,S),  % "b" is painted and well
               not painted(c,S), R is 3.        % "c" is not painted

reward(R,S) :- typeNeeded(lowQuality,S), 
               connected(a,b,S), not connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
               painted(a,S), paintedWell(a,S),     % Part "a" is painted and well
               painted(b,S), paintedWell(b,S),     % "b" is painted and well
               painted(c,S), not paintedWell(c,S), % "c" is painted, but not well  
               R is 4.        

reward(R,S) :- typeNeeded(lowQuality,S), 
               connected(a,b,S), not connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
               painted(a,S), paintedWell(a,S),     % Part "a" is painted and well
               painted(b,S), paintedWell(b,S),     % "b" is painted and well
               painted(c,S), paintedWell(c,S),     % "c" is painted and well  
               R is 3.  
%---------------------------------------------------------


reward(R,S) :- typeNeeded(lowQuality,S),  
               connected(a,b,S), connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
			   not painted(a,S),          % Part "a" is not painted 
               not painted(b,S), R is 1.

reward(R,S) :- typeNeeded(lowQuality,S), 
               connected(a,b,S), connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
			   not painted(a,S),          % Part "a" is not painted 
               painted(b,S), not paintedWell(b,S), R is 2.
			   
reward(R,S) :- typeNeeded(lowQuality,S), 
               connected(a,b,S), connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
			   not painted(a,S),          % Part "a" is not painted 
               painted(b,S), paintedWell(b,S),
               not painted(c,S), R is 2.

reward(R,S) :- typeNeeded(lowQuality,S), 
               connected(a,b,S), connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
			   not painted(a,S),          % Part "a" is not painted 
               painted(b,S), paintedWell(b,S),
               painted(c,S), not paintedWell(c,S), R is 3.

reward(R,S) :- typeNeeded(lowQuality,S),  
               connected(a,b,S), connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
                           not painted(a,S),          % Part "a" is not painted
               painted(b,S), paintedWell(b,S), 
               painted(c,S), paintedWell(c,S), R is 2.

%-------------------------------------------------------------------			   
reward(R,S) :- typeNeeded(lowQuality,S), 
               connected(a,b,S), connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
   painted(a,S), not paintedWell(a,S),    % Part "a" is painted, but not well
               not painted(b,S), R is 2.

reward(R,S) :- typeNeeded(lowQuality,S), 
               connected(a,b,S), connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
  painted(a,S), not paintedWell(a,S),     % Part "a" is painted, but not well
               painted(b,S), not paintedWell(b,S), R is 3.

reward(R,S) :- typeNeeded(lowQuality,S),  
               connected(a,b,S), connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
  painted(a,S), not paintedWell(a,S),     % Part "a" is painted, but not well
               painted(b,S), paintedWell(b,S), 
               not painted(c,S), R is 2.

reward(R,S) :- typeNeeded(lowQuality,S),  
               connected(a,b,S), connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
  painted(a,S), not paintedWell(a,S),     % Part "a" is painted, but not well
               painted(b,S), paintedWell(b,S), 
               painted(c,S), not paintedWell(c,S), R is 3.

reward(R,S) :- typeNeeded(lowQuality,S),  
               connected(a,b,S), connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
  painted(a,S), not paintedWell(a,S),     % Part "a" is painted, but not well
               painted(b,S), paintedWell(b,S), 
               painted(c,S), paintedWell(c,S), R is 2.

%-------------------------------------------------------------------

reward(R,S) :- typeNeeded(lowQuality,S), 
               connected(a,b,S), connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
               painted(a,S), paintedWell(a,S),  %Part "a" is painted and well
               not painted(b,S),                %Part "b" is not painted
               R is 1.

reward(R,S) :- typeNeeded(lowQuality,S), 
               connected(a,b,S), connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
               painted(a,S), paintedWell(a,S),  %Part "a" is painted and well
           painted(b,S), not paintedWell(b,S),  %Part "b" is painted, but not well
               R is 1.

reward(R,S) :- typeNeeded(lowQuality,S), 
               connected(a,b,S), connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
               painted(a,S), paintedWell(a,S),  %Part "a" is painted and well
               painted(b,S), paintedWell(b,S),  %Part "b" is painted and well
               not painted(c,S),                %Part "c" is not painted
               R is 1.

reward(R,S) :- typeNeeded(lowQuality,S), 
               connected(a,b,S), connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
               painted(a,S), paintedWell(a,S),  %Part "a" is painted and well
               painted(b,S), paintedWell(b,S),  %Part "b" is painted and well
           painted(c,S), not paintedWell(c,S),  %Part "c" is painted, but not well
               R is 2.

reward(R,S) :- typeNeeded(lowQuality,S), 
               connected(a,b,S), connectedWell(a,b,S), 
               connected(a,c,S), connected(b,c,S), 
               painted(a,S), paintedWell(a,S),  % Part "a" is painted and well
               painted(b,S), paintedWell(b,S),  % Part "b" is painted and well
               painted(c,S), paintedWell(c,S),  % Part "c" is painted and well
               R is 1.
%--------------------------------------------------------------------

		/* Golog procedures */

proc(new, 
  while( some(x, object(x) &
             some(y,  object(y) & -(x=y) &
               -(shaped(x) & connectedWell(x,y))) ),
    if(some(ob, object(ob) & -shaped(ob)),   /* THEN shape it */
       pi(ob, ?(object(ob) & -shaped(ob)) : shape(ob)),  /* ELSE connect it */ 
         pi(x, ?(some(ob, object(x) & object(ob) & -(x=ob) & -connectedWell(x,ob))) :
             pi(y, ?(object(y) & -(x=y) & -connectedWell(x,y)) : 
                 ( drill(y) : drill(x) : bolt(x,y)
                  #
                   if(hasSkilledWelder, weld(x,y), glue(x,y))
                  )
                )
              )
         )
       ) :
     while( some(x, object(x) & -paintedWell(x)),
	        if( some(x, object(x) & -smoothed(x)), 
                  /* then polish it*/ 
                pi(x, ?(object(x) & -smoothed(x)) : polish(x)), 
                  /* else paint it*/ 
                pi(x, ?(object(x) & -paintedWell(x)) :
                   if( skilledLabourPresent,  
	                     /* THEN */ 
                       handPaint(x),
                         /* ELSE */ 
                       (spray(x) # dip(x) )
                      )
                   )
               )
           )
).


proc(old, 
  while( some(x, object(x) &
             some(y,  object(y) & -(x=y) &
               -(shaped(x) & connectedWell(x,y))) ),
      if(some(ob, object(ob) & -shaped(ob)),   /* THEN shape it */
         pi(ob, ?(object(ob) & -shaped(ob)) : shape(ob)),  /* ELSE connect it */ 
    pi(x, ?(some(ob, object(x) & object(ob) & -(x=ob) & -connectedWell(x,ob))) : 
             pi(y, ?(object(y) & -(x=y) & -connectedWell(x,y)) : 
                 ( if(hasBolts & -(drilled(x) & drilled(y)), 
                        /* then */  
                      if( drilled(x) & -drilled(y), drill(y), drill(x) ),
                        /* else */
                      bolt(x,y)
                      )
                  #
                   if(hasSkilledWelder, weld(x,y), glue(x,y))
                  )
                )
              )
         )
       ) :
     while( some(x, object(x) & -paintedWell(x)),
	        if( some(x, object(x) & -smoothed(x)), 
                  /* then polish it*/ 
                pi(x, ?(object(x) & -smoothed(x)) : polish(x)), 
                  /* else paint it*/ 
                pi(x, ?(object(x) & -paintedWell(x)) :
                   if( skilledLabourPresent,  
	                     /* THEN */ 
                       handPaint(x),
                         /* ELSE */ (spray(x) # dip(x) )
                      % if( hasSprayGun, spray(x), dip(x) )
                      )
                   )
               )
           )
).

/* Restore situation arguments to fluents. */

restoreSitArg(typeNeeded(JobQuality),S,typeNeeded(JobQuality,S)).
restoreSitArg(connected(X,Y),S,connected(X,Y,S)).
restoreSitArg(connectedWell(X,Y),S,connectedWell(X,Y,S)).
restoreSitArg(painted(X),S,painted(X,S)).
restoreSitArg(paintedWell(X),S,paintedWell(X,S)).
restoreSitArg(shaped(X),S,shaped(X,S)).
restoreSitArg(smoothed(X),S,smoothed(X,S)).
restoreSitArg(drilled(X),S,drilled(X,S)).
restoreSitArg(skilledLabourPresent,S,skilledLabourPresent(S)).
restoreSitArg(hasSprayGun,S,hasSprayGun(S)).
restoreSitArg(hasGlue,S,hasGlue(S)).
restoreSitArg(hasBolts,S,hasBolts(S)).

restoreSitArg(hasClamps,S,hasClamps(S)).  /* factory0.dat */
restoreSitArg(hasDrill,S,hasDrill(S)).

restoreSitArg(hasMountingDevice,S,hasMountingDevice(S)). /* factory1.dat */
restoreSitArg(hasBrushes,S,hasBrushes(S)).

restoreSitArg(hasLaquer,S,hasLaquer(S)).  /* factory2.dat */

restoreSitArg(hasSkilledWelder,S,hasSkilledWelder(S)).  /* factory3.dat */
restoreSitArg(hasArcWelder,S,hasArcWelder(S)).
restoreSitArg(hasSpotWelder,S,hasSpotWelder(S)).

restoreSitArg(hasArcMaterials,S,hasArcMaterials(S)).    /* factory4.dat */
restoreSitArg(hasSpotMaterials,S,hasSpotMaterials(S)).
restoreSitArg(hasBits,S,hasBits(S)).
	

                     /* Primitive Action Declarations */

agentAction(spray(Item)).
agentAction(handPaint(Item)).
agentAction(dip(Item)).
agentAction(shape(Item)).
agentAction(drill(Item)).
agentAction(polish(Item)).
agentAction(glue(Obj1,Obj2)).
agentAction(bolt(Obj1,Obj2)).
agentAction(weld(Obj1,Obj2)).

                       /* Initial Situation */

object(a).
object(b).
object(c).

typeNeeded(highQuality,s0).

skilledLabourPresent(s0).

hasSprayGun(s0).

hasGlue(s0).

hasBolts(s0).

/* hasClamps(S) and hasDrill(S) fluents are introduced in factory0.dat */
hasClamps(s0).
hasDrill(s0).

hasMountingDevice(s0).
hasBrushes(s0).
hasLaquer(s0).

/* hasSkilledWelder(S), hasArcWelder(S), hasSpotWelder(S) are introduced in 
   factory3.dat */
hasSkilledWelder(s0).
hasArcWelder(s0).
hasSpotWelder(s0).

/*hasBits(S), hasArcMaterials(S), hasSpotMaterials(S) introduced in factory4.dat*/
hasArcMaterials(s0).
hasSpotMaterials(s0).
hasBits(s0).