# Hanoi planning problem from GraphPlan paper.

from graphplan import *

# Types

OBJ = 'Object'
INT = 'Ints'

# Instances

Rods=[Instance('RodA', OBJ),
Instance('RodB', OBJ),
Instance('RodC', OBJ)]

Disks= [Instance('Disk1', OBJ),
Instance('Disk2', OBJ),
Instance('Disk3', OBJ)]

Ints=[Instance(i,INT) for i in xrange(len(Disks)+1)]

Instances=Disks+Rods+Ints

#Start and Goal States

Start=[Proposition('top', Disks[0])]+
    [Proposition('at', Disks[i], Disks[i+1])
    for i in xrange(len(Disks)-1)]+
    [Proposition('at', Disks[-1], Rods[0])]+
    [Proposition('has_value',Ints[i] , Disks[i])
    for i in xrange(len(Disks))]+
    [Proposition('top', Rods[i])
    for i in xrange(1,len(Rods))]+
    [Proposition('has_value',Ints[-1] , rod)
    for rod in Rods]

Goal=[Proposition('at', Disks[i], Disks[i+1])
    for i in xrange(len(Disks)-1)]+
    [Proposition('at', Disks[-1], Rods[-1])]

# Variables

v_d = Variable('d', OBJ)
v_dfrom = Variable('dfrom', OBJ)
v_dto = Variable('dto', OBJ)
v_i1 = Variable('i1', INT)
v_i2 = Variable('i2', INT)

# Operators

o_move = Operator('move',
    # Preconditions
    [Proposition('top', v_d),
    Proposition('at', v_d, v_dfrom),
    Proposition('not_equal', v_d, v_dto),
    Proposition('top', v_dto),
    Proposition('has_value', v_i1, v_d),
    Proposition('has_value', v_i2, v_dto),
    Proposition('less_than', v_i1, v_i2)],
    # Adds
    [Proposition('at', v_d, v_dto),
    Proposition('top', v_dfrom)],
    # Deletes
    [Proposition('at', v_d, v_dfrom),
    Proposition('top', v_dto)])

Operators=[o_move]

#Problems

prob1 = PlanningProblem('prob1',
    # Instances
    Instances,
    # Operators
    Operators,
    # Initial state
    Start,
    # Goals
    Goal)

prob1.solve()
prob1.display()

# prob1.dump()