;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Some sample Planning problems for the schedule world.
;;; And a random problem generator.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;; state1-goal1
(define state1 '((current-time 0)
               (has-bit punch 1)
               (has-bit punch 2)
               (has-bit punch 3)
               (has-bit drill-press 1)
               (has-bit drill-press 2)
               (has-bit drill-press 3)
               (has-paint spray-painter red)
               (has-paint spray-painter black)
               (has-paint immersion-painter red)
               (has-paint immersion-painter black)
               (can-orient punch front)
               (can-orient drill-press front)
               (object A)
               (object B)
               (shape A oblong)
	       (temperature A cold)
	       (surface-condition A rough)
	       (shape B cylindrical)
	       (temperature B cold)
	       (surface-condition B smooth)
	       (painted B red)))

(define goal1 '((shape A cylindrical)
              (surface-condition B polished)))

;;; state2-goal2

(define state2 '((current-time 0)
               (has-bit punch 1)
               (has-bit punch 2)
               (has-bit punch 3)
               (has-bit drill-press 1)
               (has-bit drill-press 2)
               (has-bit drill-press 3)
               (has-paint spray-painter red)
               (has-paint spray-painter black)
               (has-paint immersion-painter red)
               (has-paint immersion-painter black)
               (can-orient punch front)
               (can-orient drill-press front)
               (object A)
               (object B)
               (object C)
               
               (shape A rectangular)
	       (temperature A cold)
	       (surface-condition A rough)
	       (painted A blue)
	       (has-hole A 2 FRONT)
               
	       (shape B flat)
	       (temperature B cold)
	       (surface-condition B polished)
               
	       (shape C oblong)
	       (temperature C cold)
	       (surface-condition C rough)))

(define goal2 '((shape A cylindrical) 
              (surface-condition A smooth)
              (surface-condition B polished)))

;;; state3-goal3

(define state3 '((current-time 0)
               (has-bit punch 1)
               (has-bit punch 2)
               (has-bit punch 3)
               (has-bit drill-press 1)
               (has-bit drill-press 2)
               (has-bit drill-press 3)
               (has-paint spray-painter red)
               (has-paint spray-painter black)
               (has-paint immersion-painter red)
               (has-paint immersion-painter black)
               (can-orient punch front)
               (can-orient drill-press front)
               (object A)
               (object B)
               (object C)
               (object D)
               
               (shape A rectangular)
	       (temperature A cold)
	       (surface-condition A rough)
	       (painted A blue)
	       (has-hole A 2 FRONT)
               
	       (shape B flat)
	       (temperature B cold)
	       (surface-condition B rough)
               
	       (shape C oblong)
	       (temperature C cold)
	       (surface-condition C rough)
	       
	       (shape D oblong)
	       (temperature D cold)
	       (surface-condition D smooth)
	       (painted D BLACK)))


(define goal3 '((shape A cylindrical) 
              (painted A BLACK)
              (surface-condition A polished)
              
              (shape B cylindrical) 
              (surface-condition B polished)
              
              (painted C RED)
              (has-hole C 2 FRONT)
              (surface-condition C smooth)
              
              (shape D cylindrical) 
              (has-hole D 3 FRONT)))

;;; state4 goal4

(define state4 '((current-time 0)
               (has-bit punch 1)
               (has-bit punch 2)
               (has-bit punch 3)
               (has-bit drill-press 1)
               (has-bit drill-press 2)
               (has-bit drill-press 3)
               (has-paint spray-painter red)
               (has-paint spray-painter black)
               (has-paint immersion-painter red)
               (has-paint immersion-painter black)
               (can-orient punch front)
               (can-orient drill-press front)
               (object A)
               (object B)
               (object C)
               (object D)
               (object E)
               
               (shape A rectangular)
	       (temperature A cold)
	       (surface-condition A rough)
	       (painted A blue)
	       (has-hole A 2 FRONT)
	       
	       (shape B flat)
	       (temperature B cold)
	       (surface-condition B rough)
	       
	       (shape C oblong)
	       (temperature C cold)
	       (surface-condition C rough)

	       (shape D oblong)
	       (temperature D cold)
	       (surface-condition D smooth)
	       (painted D BLACK)

	       (shape E cylindrical)
	       (temperature E cold)
	       (surface-condition E rough)))

(define goal4 '((shape A cylindrical) 
              (painted A BLACK)
              (surface-condition A polished)
              
              (shape B cylindrical) 
              (surface-condition B polished)
              
              (painted C RED)
              (has-hole C 2 FRONT)
              (surface-condition C smooth)
              
              (shape D cylindrical) 
              (has-hole D 3 FRONT)
              
              (painted E BLACK)
              (surface-condition E smooth)))

;;; state5 goal5

(define state5 '((current-time 0)
               (has-bit punch 1)
               (has-bit punch 2)
               (has-bit punch 3)
               (has-bit drill-press 1)
               (has-bit drill-press 2)
               (has-bit drill-press 3)
               (has-paint spray-painter red)
               (has-paint spray-painter black)
               (has-paint immersion-painter red)
               (has-paint immersion-painter black)
               (can-orient punch front)
               (can-orient drill-press front)
               (object A)
               (object B)
               (object C)
               (object D)
               (object E)
               (object F)
               (object G)
               (object H)
               (object I)
               
               (shape A rectangular)
	       (temperature A cold)
	       (surface-condition A rough)
	       (painted A blue)
	       (has-hole A 2 FRONT)
	       
	       (shape B flat)
	       (temperature B cold)
	       (surface-condition B rough)
	       
	       (shape C oblong)
	       (temperature C cold)
	       (surface-condition C rough)

	       (shape D oblong)
	       (temperature D cold)
	       (surface-condition D smooth)
	       (painted D BLACK)

	       (shape E cylindrical)
	       (temperature E cold)
	       (surface-condition E rough)
	       
	       (shape F oblong)
	       (temperature F cold)
	       (surface-condition F rough)

	       (shape G oblong)
	       (temperature G cold)
	       (surface-condition G smooth)
	       (painted G BLACK)

	       (shape H cylindrical)
	       (temperature H cold)
	       (surface-condition H rough)
	       
	       (shape I rectangular)
	       (temperature I cold)
	       (surface-condition I rough)
	       (painted I blue)
	       (has-hole I 2 FRONT)))

(define goal5 
      '((shape A cylindrical) 
        (painted A BLACK)
        (surface-condition A polished)
        
        (shape B cylindrical) 
        (surface-condition B polished)
        
        (painted C RED)
        (has-hole C 2 FRONT)
        (surface-condition C smooth)
        
        (shape D cylindrical) 
        (has-hole D 3 FRONT)
        
        (painted E BLACK)
        (surface-condition E smooth)
        (has-hole E 2 FRONT)
        
        (surface-condition F polished)
        
        (shape G cylindrical) 
        
        (painted H BLACK)
        
        (painted I BLACK)
        (surface-condition I polished)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Random problems.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; (random-world size) --- size is an integer.
;;;                         Return a world list containing size objects.
;;; (random-goal size)  --- Return a goal list of size new features
;;;                         To achieve. CALL (random-world) FIRST.
;;;
;;; Functions for generating a random schedule world initial state and a goal
;;; state. We generate tests by with the following parameters:
;;;
;;; numobjects: how many different objects we schedule.
;;; numgoals: the length of the goal-state.
;;; Given numobjects, numgoals.
;;;  (1) generate a list of numobjects objects.
;;;      (a) generate an initial world state, by randomly selecting values
;;;           for each of the four features: shape, surface-condition, 
;;;           painted, and has-hole (the other predicates are always fixed).
;;;      (b) create a goal list by again selecting random features
;;;          among the previous ones, not true in init state, for each object.
;;;      (c) generate a goal-state by randomly selecting numgoals from the
;;;          goal list.
;;;      (d) run the planner with the initial world state in (a) and the goal
;;;          state in (b).
;;;  Hence, we vary the size of the goal state using numgoals.
;;;  For Tlplan, although the depth of expansion is the same for goal-states 
;;;  of equal length, those built from a small number-of-objects tend to be 
;;;  a little bit easier in tlplan, because the overheads at the level of 
;;;  action-application (i.e., node overhead) is smaller.
;;;  
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(define *objects* '(A B C D E F G H I J K L M N O Q P R S U V W Z
		    A1 B1 C1 D1 E1 F1 G1 H1 I1 J1 K1 L1 M1 N1 O1 Q1 P1
		    R1 S1 U1 V1 W1 Z1))
(define *colors* '(RED BLACK BLUE YELLOW))
(define *hole-sizes* '(1 2 3))
(define *orientations* '(FRONT BACK))
(define *shapes* '(oblong circular cylindrical))
(define *surfaces* '(polished rough smooth))

(define (random-select-predicates num set)
  "randomly select num predicates from the set"
  (let ((result '())
	(limit (min num (length set))))
    (do ((index 0 (+ index 1)))
	((>= index limit) result)
      (let((f (nth (random (length set)) set)))	
	(set! result (cons f result)	)
	(set! set (remove-if (lambda (x) (equal? x f)) set))))))

(define (get-objects n)
  "returns n different objects"
  (list-head *objects* (min (length *objects*) n)))

(define (random-tool-predicates)
  "List of predicates that must be added to each initial world state"
  (let((result '()))
    (set! result (cons `(current-time 0) result))
    (for-each (lambda (s)
		(for-each (lambda (p)
			    (set! result (cons `(has-bit ,p ,s) result)))
			  `(punch drill-press)))
	      *hole-sizes*)
    (for-each (lambda (c)
		(for-each (lambda (p)
			    (set! result (cons `(has-paint ,p ,c) result)))
			  `(spray-painter immersion-painter)))
	      *colors*)
    (for-each (lambda (o)
		(set! result (cons `(can-orient punch ,o) result))
		(set! result (cons `(can-orient drill-press ,o) result)))
	      *orientations*)
    result))

(define (random-world-feature-predicates objects)
  "randomly select possible initial values for the features of objects."
  (let ((result '()))
    (for-each 
     (lambda (obj)
       (set! result (cons `(temperature ,obj cold) result))
       (set! result (cons `(has-hole ,obj 
				     ,(nth (random (length *hole-sizes*)) 
					   *hole-sizes*)
				     ,(nth (random (length *orientations*)) 
					   *orientations*))
			  result))
       (set! result (cons `(painted ,obj ,(nth (random (length *colors*)) 
					       *colors*)) 
			  result))
       (set! result (cons `(surface-condition ,obj 
					      ,(nth (random (length 
							     *surfaces*))
						    *surfaces*))
			   result))
       (set! result (cons `(shape ,obj ,(nth (random (length *shapes*)) 
					     *shapes*))
			  result)))
     objects)
    result))

(define random-world-list '())

(define (random-world size)
  "Returns a randomly selected world, given the objects"
  (let ((objects (get-objects size)))
    (set! random-world-list
	  (append (random-world-feature-predicates objects)
		  (random-tool-predicates)
		  (map (lambda(obj) (list 'object obj)) objects)))
    random-world-list))

(define (random-goal size)
  "Returns a randomly selected list of features that can be achieved
   by tools but not already true in the world-list"
  (let ((result '())
	(dfeature '())) ;; domain of a feature
    (for-each 
     (lambda (f)
       (case (car f)
	 (hole-size 
	  (set! dfeature (remove-if (lambda (x) (eq? x (third f)))
				    *hole-sizes*))
	  (set! result 
		(cons (list 'hole-size (second f)
			    (nth (random (length dfeature)) dfeature)
			    (nth (random (length *orientations*)) 
				 *orientations*))
		      result)))
	 (painted
	  (set! dfeature (remove-if (lambda (x) (eq? x (third f))) *colors*))
	  (set! result 
		(cons (list 'painted (second f)
			    (nth (random (length dfeature)) dfeature))
		      result)))
	 (surface-condition 
	  (set! dfeature (remove-if (lambda (x) (eq? x (third f))) *surfaces*))
	  (set! result 
		(cons (list 'surface-condition (second f)
			    (nth (random (length dfeature)) dfeature))
		      result)))
	 (shape 
	  (if (not (eq? (third f) 'cylindrical))
	      (set! result 
		    (cons (list 'shape (second f) 'cylindrical) 
			  result))))))
     random-world-list)
    (random-select-predicates size result)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


