#! /bin/bash ############################################################################# # Propositional Railway Domain # ############################################################################# # Copyright (C) 2006 by Muhammad Abdul Hakim Newton mahnewton@gmail.com # # # # This program is free software; you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation; either version 2 of the License, or # # (at your option) any later version. # # # # This program is distributed in the hope that it will be useful, # # but WITHOUT ANY WARRANTY; without even the implied warranty of # # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # # GNU General Public License for more details. # # # # You should have received a copy of the GNU General Public License # # along with this program; if not, write to the # # Free Software Foundation, Inc., # # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # ############################################################################# # global variables declare PROGRAM=$0 # program name declare -i COUNT=$# # parameter count declare DOMAIN=$(basename $0 | sed -r s/\.[[:alnum:]_-]+$//) # domain and file names are same declare OPTION=$1 # generate the domain (-d) or a problem (-p) or usage () # global functions declare -f explain declare -f domain declare -f problem # explain usage and game rules function explain { echo echo "Usage for domain:" echo " $PROGRAM -d [ey|en]" echo " ey : use object equality (default)" echo " en : do not use object equality" echo "Usage for problem:" echo " $PROGRAM -p #place [#seed]" echo " #place : number of places (>= 2)" echo " #seed : optional seed for random number generation" echo "Description:" echo " > The propositional Railway represents a rail-way construction scenario." echo " > Train stations are to be built in all given places." echo " > Rail lines are to be built between pairs of stations." echo " > Trains are to be built at different stations." echo " > The places can have woodlands, mountains, coal mines, and metalliferous areas." echo " > The places are therefore sources of resources like timber, stone, coal, and iron." echo " > A cart is available to carry the resources from one place to another." echo return 2 } # generate the domain function domain { echo echo "(define" echo " (domain $DOMAIN)" echo " (:requirements" if [[ -z $EQUALITY || $EQUALITY == "ey" ]] then echo " :strips :typing :equality" else echo " :strips :typing" fi echo " )" echo " (:types" echo " place resource" echo " )" echo " (:constants" echo " timber coal stone iron - resource" echo " )" echo " (:predicates" echo " (woodland ?p - place)" echo " (mountain ?p - place)" echo " (metalliferous ?p - place)" echo " (coal-mine ?p - place)" echo " (cart-at ?p - place)" echo " (cart-empty)" echo " (cart-holds ?r - resource)" echo " (place-stock ?p - place ?r - resource)" echo " (place-empty ?p - place ?r - resource)" echo " (rail-station ?p - place)" echo " (rail-road ?p ?q - place)" echo " (train-at ?p - place)" echo " )" echo " (:action load-cart" echo " :parameters (?p - place ?r - resource)" echo " :precondition" echo " (and" echo " (cart-at ?p)" echo " (place-stock ?p ?r)" echo " (cart-empty)" echo " )" echo " :effect" echo " (and" echo " (not (place-stock ?p ?r))" echo " (not (cart-empty))" echo " (cart-holds ?r)" echo " (place-empty ?p ?r)" echo " )" echo " )" echo " (:action unload-cart" echo " :parameters (?p - place ?r - resource)" echo " :precondition" echo " (and" echo " (cart-at ?p)" echo " (cart-holds ?r)" echo " (place-empty ?p ?r)" echo " )" echo " :effect" echo " (and" echo " (not (cart-holds ?r))" echo " (not (place-empty ?p ?r))" echo " (place-stock ?p ?r)" echo " (cart-empty)" echo " )" echo " )" echo " (:action move-cart" echo " :parameters (?p ?q - place)" echo " :precondition" echo " (and" echo " (cart-at ?p)" if [[ -z $EQUALITY || $EQUALITY == "ey" ]] then echo " (not (= ?p ?q))" fi echo " )" echo " :effect" echo " (and" echo " (not (cart-at ?p))" echo " (cart-at ?q)" echo " )" echo " )" echo " (:action fell-timber" echo " :parameters (?p - place)" echo " :precondition" echo " (and" echo " (place-empty ?p timber)" echo " (woodland ?p)" echo " )" echo " :effect" echo " (and" echo " (not (place-empty ?p timber))" echo " (place-stock ?p timber)" echo " )" echo " )" echo " (:action mine-coal" echo " :parameters (?p - place)" echo " :precondition" echo " (and" echo " (place-empty ?p coal)" echo " (coal-mine ?p)" echo " )" echo " :effect" echo " (and" echo " (not (place-empty ?p coal))" echo " (place-stock ?p coal)" echo " )" echo " )" echo " (:action break-stone" echo " :parameters (?p - place)" echo " :precondition" echo " (and" echo " (place-empty ?p stone)" echo " (mountain ?p)" echo " )" echo " :effect" echo " (and" echo " (not (place-empty ?p stone))" echo " (place-stock ?p stone)" echo " )" echo " )" echo " (:action make-iron" echo " :parameters (?p - place)" echo " :precondition" echo " (and" echo " (place-empty ?p iron)" echo " (metalliferous ?p)" echo " )" echo " :effect" echo " (and" echo " (not (place-empty ?p iron))" echo " (place-stock ?p iron)" echo " )" echo " )" echo " (:action build-station" echo " :parameters (?p - place)" echo " :precondition" echo " (and" echo " (place-stock ?p timber)" echo " (place-stock ?p stone)" echo " )" echo " :effect" echo " (and" echo " (not (place-stock ?p timber))" echo " (not (place-stock ?p stone))" echo " (place-empty ?p timber)" echo " (place-empty ?p stone)" echo " (rail-station ?p)" echo " )" echo " )" echo " (:action build-line" echo " :parameters (?p ?q - place)" echo " :precondition" echo " (and" echo " (rail-station ?p)" echo " (rail-station ?q)" if [[ -z $EQUALITY || $EQUALITY == "ey" ]] then echo " (not (= ?p ?q))" fi echo " (place-stock ?p timber)" echo " (place-stock ?p iron)" echo " (place-stock ?p stone)" echo " (place-stock ?q timber)" echo " (place-stock ?q iron)" echo " (place-stock ?q stone)" echo " )" echo " :effect" echo " (and" echo " (not (place-stock ?p timber))" echo " (not (place-stock ?p iron))" echo " (not (place-stock ?p stone))" echo " (not (place-stock ?q timber))" echo " (not (place-stock ?q iron))" echo " (not (place-stock ?q stone))" echo " (place-empty ?p timber)" echo " (place-empty ?p iron)" echo " (place-empty ?p stone)" echo " (place-empty ?q timber)" echo " (place-empty ?q iron)" echo " (place-empty ?q stone)" echo " (rail-road ?p ?q)" echo " )" echo " )" echo " (:action build-train" echo " :parameters (?p - place)" echo " :precondition" echo " (and" echo " (rail-station ?p)" echo " (place-stock ?p timber)" echo " (place-stock ?p coal)" echo " (place-stock ?p iron)" echo " )" echo " :effect" echo " (and" echo " (not (place-stock ?p timber))" echo " (not (place-stock ?p coal))" echo " (not (place-stock ?p iron))" echo " (place-empty ?p timber)" echo " (place-empty ?p coal)" echo " (place-empty ?p iron)" echo " (train-at ?p)" echo " )" echo " )" echo ")" echo return 0 } function problem { if (( SEED != 0 )) # if a seed is given, use it then RANDOM=$SEED fi echo echo "(define" echo " (problem $DOMAIN-$PLACE)" echo " (:domain $DOMAIN)" echo " (:objects" for (( i = 0; i < PLACE; i++ )) do echo " p$i" # places done echo " - place" echo " )" echo " (:init" declare -i WOODLAND=0 declare -i MOUNTAIN=0 declare -i METALLIFEROUS=0 declare -i COALMINE=0 for (( i = 0; i < PLACE; i++ )) do if (( RANDOM % 2 == 0 )) # distribute woodlands then echo " (woodland p$i)" WOODLAND=$(( WOODLAND + 1 )) fi if (( RANDOM % 3 == 0 )) # distribute mountains then echo " (mountain p$i)" MOUNTAIN=$(( MOUNTAIN + 1 )) fi if (( RANDOM % 5 == 0 )) then echo " (metalliferous p$i)" # distribute metalliferous areas METALLIFEROUS=$(( METALLIFEROUS + 1 )) fi if (( RANDOM % 5 == 0 )) then echo " (coal-mine p$i)" # distribute coal-mines COALMINE=$(( COALMINE + 1 )) fi done if [[ $WOODLAND -eq 0 ]] # ensure there is at least one woodland then echo " (woodland p$((RANDOM % PLACE)))" fi if [[ $MOUNTAIN -eq 0 ]] # ensure there is at least one mountain then echo " (mountain p$((RANDOM % PLACE)))" fi if [[ $METALLIFEROUS -eq 0 ]] # ensure there is at least one metalliferous region then echo " (metalliferous p$((RANDOM % PLACE)))" fi if [[ $COALMINE -eq 0 ]] # ensure there is at least one coal-mine then echo " (coal-mine p$((RANDOM % PLACE)))" fi for (( i = 0; i < PLACE; i++ )) do echo " (place-empty p$i timber)" echo " (place-empty p$i coal)" echo " (place-empty p$i iron)" echo " (place-empty p$i stone)" done echo " (cart-at p$((RANDOM % PLACE)))" # cart is at a random place echo " (cart-empty)" # cart empty initially echo " )" echo " (:goal" echo " (and" declare -i TRAIN=0 for(( i = 0; i < PLACE; i++)) do echo " (rail-station p$i)" # each place has a rail station if (( RANDOM % PLACE == 0 )) then echo " (train-at p$i)" # a place might have a train TRAIN=$(( TRAIN + 1 )) fi done if [[ $TRAIN -eq 0 ]] # ensure there is at least one train then echo " (train-at p$((RANDOM % PLACE)))" fi declare -i CONNECTED for (( i = 0; i < PLACE; i++ )) do CONNECTED[i]=i # initially all stations are disconnected done for (( i = 0; i < PLACE; i++ )) do for (( j = i + 1; j < PLACE; j++ )) do if (( (RANDOM % PLACE) * (RANDOM % PLACE) < PLACE )) then echo " (rail-road p$i p$j)" # a pair of places might be connected if (( CONNECTED[$i] < CONNECTED[$j])) # a connected pair are in the samecluster then SMALL=${CONNECTED[$i]} BIG=${CONNECTED[$j]} else SMALL=${CONNECTED[$j]} BIG=${CONNECTED[$i]} fi for (( k = 0; k < PLACE; k++ )) # propagate do if (( CONNECTED[$k] == BIG )) then CONNECTED[$k]=$SMALL fi done fi done done for (( i = 0; i < PLACE; i++ )) do if (( CONNECTED[$i] != 0 )) # if a station is not in the cluster of station 0 then j=$((RANDOM % PLACE)) # select a station in the cluster of station 0 while (( CONNECTED[$j] != 0 )) do j=$(( RANDOM % PLACE )) done CONNECTED[$i]=0 # this station is now connected with the selected station echo " (rail-road p$i p$j)" for (( k = 0; k < PLACE; k++ )) # propagate do if (( CONNECTED[$k] == i )) then CONNECTED[$k]=0 fi done fi done echo " )" echo " )" echo ")" echo return 0 } # main body if [[ $OPTION == "-p" ]] then declare -i PLACE=$2 # number of places declare -i SEED=$3 # optional seed for random number generation if (( ($COUNT == 2 || $COUNT == 3) && $PLACE >= 2)) then problem else echo echo " Error in parameter count or parameter values." echo explain fi elif [[ $OPTION == "-d" ]] then declare EQUALITY=$2 # optional equality (ey) no-equality (en) if [[ $COUNT -eq 1 || $COUNT -eq 2 && $EQUALITY == e[yn] ]] then domain else echo echo " Error in parameter count or parameter values." echo explain fi else explain fi exit $?