# Path: misc/utils.py
# SEPARATOR = '\n'+85*'-'+'\n'
# def arg_info(frame, ignore=['self']):
# def function_name(stack): # NOTE - stack = inspect.stack()
# def get_path(frame):
# def get_directory(abs_path):
# def global_fn(name):
# def refresh(module_name):
# 
# Path: sas/pop.py
# def pop_solve(initial, goal, operators, max_length=float('inf')):
#   initial_plan = PartialPlan([initial, goal],
#                          {(initial, goal)},
#                          [(g, goal) for g in goal.cond()],
#                          [])
#   #operators.sort()
#   iterations = 0
#   expanded = 1
#   if initial_plan.solved():
#     return initial_plan.extract_plan(), (iterations, expanded)
# 
#   BFS = False
#   if BFS:
#     queue = deque([initial_plan])
#   else:
#     queue = [(initial_plan.rank(operators), initial_plan)]
#   while queue:
#     #queue = deque(sorted(queue, key=lambda q: q.rank()))
#     if BFS:
#       plan = queue.popleft()
#     else:
#       _, plan = heappop(queue)
#     #print(len(queue), sorted(queue, key=lambda q: q.rank()))
#     print(iterations, expanded, plan.heuristic(operators), plan.length()) #, len(neighbors)
#     #print(plan)
#     #raw_input()
#     iterations += 1
#     for new_plan in plan.neighbors(operators):
#       if new_plan.length() > max_length:
#         continue
#       expanded += 1
#       if new_plan.solved():
#         return new_plan.extract_plan(), (iterations, expanded)
#       if BFS:
#         queue.append(new_plan)
#       else:
#         heappush(queue, (new_plan.rank(operators), new_plan))
#   return None, (iterations, expanded)
# 
# Path: sas/relaxed_pop.py
# def relaxed_pop(initial, goal, operators, QueueClass=FIFOPriorityQueue):
#   initial_plan = get_initial_plan(initial, goal)
#   #operators.sort()
#   iterations = 0
#   expanded = 1
# 
#   #priority_fn = lambda p: p.length() # NOTE - super slow
#   #priority_fn = lambda p: p.length() + p.unsatisfied_goals()
#   priority_fn = lambda p: p.unsatisfied_goals()
# 
#   if initial_plan.solved():
#     return initial_plan.extract_plan(), (iterations, expanded)
# 
#   queue = QueueClass()
#   queue.push(priority_fn(initial_plan), initial_plan)
#   while queue:
#     plan = queue.pop()
#     print(iterations, expanded, plan.length(), plan.unsatisfied_goals(), priority_fn(plan))
#     iterations += 1
#     for new_plan in plan.neighbors(operators):
#       expanded += 1
#       if new_plan.solved():
#         return new_plan.extract_plan(), (iterations, expanded)
#       queue.push(priority_fn(new_plan), new_plan)
#   return None, (iterations, expanded)
# 
# Path: planner/meta/forward_hierarchy.py
# def fixed_search(start, goal, operators, subsearch, hierarchy, level=0):
#   # Modify operators wrt hierarchy but not goal?
#   # Can always modify operators to produce additional effects from the projected preconditions
# 
#   modified_operators = []
#   #for operator in operators + [goal]: # TODO - include goal
#   for operator in operators:
#     modified_operator = deepcopy(operator)
#     modified_operator.original = operator
#     for v, val in operator.cond():
#       if v not in operator.effects: # NOTE - adds operator image
#         modified_operator.effects[v] = val
#       if hierarchy((v, val), operator) > level:
#         del modified_operator.conditions[v]
#     modified_operators.append(modified_operator)
# 
#   plan, state_space = subsearch(start, goal, modified_operators)
#   #print(plan.length)
#   if plan is None:
#     return None, None
# 
#   state = start
#   sequence = []
#   #for operator in plan.operators + [goal]: # TODO - should I assume that the last operator achieves the goal or not?
#   for modified_operator in plan.operators:
#     operator = modified_operator.original
#     if state not in operator:
#       #print(state, operator)
#       #print()
#       subplan, subdata = fixed_search(state, Goal(operator.conditions), operators, subsearch, hierarchy, level=level+1)
#       if subplan is None:
#         return None, None
#       state = subplan.get_states()[-1]
#       sequence += subplan.operators
#     if operator != goal:
#       state = operator(state)
#       sequence.append(operator)
#   return Plan(start, sequence), None # TODO - merge state-spaces
# 
# def pp_hierarchy_level(cond, operator):
#   v, val = cond
#   if v == 'robot':
#     return 1
#   return 0


from misc.profiling import *
from misc.utils import SEPARATOR, randomize
from sas.utils import *
from sas.pop import pop_solve
from sas.relaxed_pop import relaxed_pop
from planner.meta.forward_hierarchy import fixed_search, pp_hierarchy_level
import sas.domains as domains
import sys
import getopt
import time
import datetime
import argparse
#!/usr/bin/env python

from __future__ import print_function


DIRECTORY = './simulations/sas/planning/'

def solve(problem, print_profile):
  initial, goal, operators = problem()
  dt = datetime.datetime.now()
  directory = DIRECTORY + '{}/{}/{}/'.format(
      problem.__name__, dt.strftime('%Y-%m-%d'), dt.strftime('%H-%M-%S'))
  print(SEPARATOR + '\nSolving sas problem ' + problem.__name__)

  def execute():
    start_time = time.time()
    try:

# Path: misc/utils.py
# SEPARATOR = '\n'+85*'-'+'\n'
# def arg_info(frame, ignore=['self']):
# def function_name(stack): # NOTE - stack = inspect.stack()
# def get_path(frame):
# def get_directory(abs_path):
# def global_fn(name):
# def refresh(module_name):
# 
# Path: sas/pop.py
# def pop_solve(initial, goal, operators, max_length=float('inf')):
#   initial_plan = PartialPlan([initial, goal],
#                          {(initial, goal)},
#                          [(g, goal) for g in goal.cond()],
#                          [])
#   #operators.sort()
#   iterations = 0
#   expanded = 1
#   if initial_plan.solved():
#     return initial_plan.extract_plan(), (iterations, expanded)
# 
#   BFS = False
#   if BFS:
#     queue = deque([initial_plan])
#   else:
#     queue = [(initial_plan.rank(operators), initial_plan)]
#   while queue:
#     #queue = deque(sorted(queue, key=lambda q: q.rank()))
#     if BFS:
#       plan = queue.popleft()
#     else:
#       _, plan = heappop(queue)
#     #print(len(queue), sorted(queue, key=lambda q: q.rank()))
#     print(iterations, expanded, plan.heuristic(operators), plan.length()) #, len(neighbors)
#     #print(plan)
#     #raw_input()
#     iterations += 1
#     for new_plan in plan.neighbors(operators):
#       if new_plan.length() > max_length:
#         continue
#       expanded += 1
#       if new_plan.solved():
#         return new_plan.extract_plan(), (iterations, expanded)
#       if BFS:
#         queue.append(new_plan)
#       else:
#         heappush(queue, (new_plan.rank(operators), new_plan))
#   return None, (iterations, expanded)
# 
# Path: sas/relaxed_pop.py
# def relaxed_pop(initial, goal, operators, QueueClass=FIFOPriorityQueue):
#   initial_plan = get_initial_plan(initial, goal)
#   #operators.sort()
#   iterations = 0
#   expanded = 1
# 
#   #priority_fn = lambda p: p.length() # NOTE - super slow
#   #priority_fn = lambda p: p.length() + p.unsatisfied_goals()
#   priority_fn = lambda p: p.unsatisfied_goals()
# 
#   if initial_plan.solved():
#     return initial_plan.extract_plan(), (iterations, expanded)
# 
#   queue = QueueClass()
#   queue.push(priority_fn(initial_plan), initial_plan)
#   while queue:
#     plan = queue.pop()
#     print(iterations, expanded, plan.length(), plan.unsatisfied_goals(), priority_fn(plan))
#     iterations += 1
#     for new_plan in plan.neighbors(operators):
#       expanded += 1
#       if new_plan.solved():
#         return new_plan.extract_plan(), (iterations, expanded)
#       queue.push(priority_fn(new_plan), new_plan)
#   return None, (iterations, expanded)
# 
# Path: planner/meta/forward_hierarchy.py
# def fixed_search(start, goal, operators, subsearch, hierarchy, level=0):
#   # Modify operators wrt hierarchy but not goal?
#   # Can always modify operators to produce additional effects from the projected preconditions
# 
#   modified_operators = []
#   #for operator in operators + [goal]: # TODO - include goal
#   for operator in operators:
#     modified_operator = deepcopy(operator)
#     modified_operator.original = operator
#     for v, val in operator.cond():
#       if v not in operator.effects: # NOTE - adds operator image
#         modified_operator.effects[v] = val
#       if hierarchy((v, val), operator) > level:
#         del modified_operator.conditions[v]
#     modified_operators.append(modified_operator)
# 
#   plan, state_space = subsearch(start, goal, modified_operators)
#   #print(plan.length)
#   if plan is None:
#     return None, None
# 
#   state = start
#   sequence = []
#   #for operator in plan.operators + [goal]: # TODO - should I assume that the last operator achieves the goal or not?
#   for modified_operator in plan.operators:
#     operator = modified_operator.original
#     if state not in operator:
#       #print(state, operator)
#       #print()
#       subplan, subdata = fixed_search(state, Goal(operator.conditions), operators, subsearch, hierarchy, level=level+1)
#       if subplan is None:
#         return None, None
#       state = subplan.get_states()[-1]
#       sequence += subplan.operators
#     if operator != goal:
#       state = operator(state)
#       sequence.append(operator)
#   return Plan(start, sequence), None # TODO - merge state-spaces
# 
# def pp_hierarchy_level(cond, operator):
#   v, val = cond
#   if v == 'robot':
#     return 1
#   return 0


# Path: solve_sas.py
from misc.profiling import *
from misc.utils import SEPARATOR, randomize
from sas.utils import *
from sas.pop import pop_solve
from sas.relaxed_pop import relaxed_pop
from planner.meta.forward_hierarchy import fixed_search, pp_hierarchy_level
import sas.domains as domains
import sys
import getopt
import time
import datetime
import argparse

#!/usr/bin/env python

from __future__ import print_function


DIRECTORY = './simulations/sas/planning/'

def solve(problem, print_profile):
  initial, goal, operators = problem()
  dt = datetime.datetime.now()
  directory = DIRECTORY + '{}/{}/{}/'.format(
      problem.__name__, dt.strftime('%Y-%m-%d'), dt.strftime('%H-%M-%S'))
  print(SEPARATOR + '\nSolving sas problem ' + problem.__name__)

  def execute():
    start_time = time.time()
    try:

      output = default_plan(initial, goal, randomize(operators))