lp_utils.py 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. from aimacode.logic import associate
  2. from aimacode.utils import expr
  3. class FluentState():
  4. """ state object for planning problems as positive and negative fluents
  5. """
  6. def __init__(self, pos_list, neg_list):
  7. self.pos = pos_list
  8. self.neg = neg_list
  9. def sentence(self):
  10. return expr(conjunctive_sentence(self.pos, self.neg))
  11. def pos_sentence(self):
  12. return expr(conjunctive_sentence(self.pos, []))
  13. def conjunctive_sentence(pos_list, neg_list):
  14. """ returns expr conjuntive sentence given positive and negative fluent lists
  15. :param pos_list: list of fluents
  16. :param neg_list: list of fluents
  17. :return: expr sentence of fluent conjunction
  18. e.g. "At(C1, SFO) ∧ ~At(P1, SFO)"
  19. """
  20. clauses = []
  21. for f in pos_list:
  22. clauses.append(expr("{}".format(f)))
  23. for f in neg_list:
  24. clauses.append(expr("~{}".format(f)))
  25. return associate('&', clauses)
  26. def encode_state(fs: FluentState, fluent_map: list) -> str:
  27. """ encode fluents to a string of T/F using mapping
  28. :param fs: FluentState object
  29. :param fluent_map: ordered list of possible fluents for the problem
  30. :return: str eg. "TFFTFT" string of mapped positive and negative fluents
  31. """
  32. state_tf = []
  33. for fluent in fluent_map:
  34. if fluent in fs.pos:
  35. state_tf.append('T')
  36. else:
  37. state_tf.append('F')
  38. return "".join(state_tf)
  39. def decode_state(state: str, fluent_map: list) -> FluentState:
  40. """ decode string of T/F as fluent per mapping
  41. :param state: str eg. "TFFTFT" string of mapped positive and negative fluents
  42. :param fluent_map: ordered list of possible fluents for the problem
  43. :return: fs: FluentState object
  44. lengths of state string and fluent_map list must be the same
  45. """
  46. fs = FluentState([], [])
  47. for idx, char in enumerate(state):
  48. if char == 'T':
  49. fs.pos.append(fluent_map[idx])
  50. else:
  51. fs.neg.append(fluent_map[idx])
  52. return fs