variable.py 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. from contextlib import contextmanager
  2. from .utils import hashable
  3. from .dispatch import dispatch
  4. _global_logic_variables = set() # type: ignore[var-annotated]
  5. _glv = _global_logic_variables
  6. class Var:
  7. """ Logic Variable """
  8. _id = 1
  9. def __new__(cls, *token):
  10. if len(token) == 0:
  11. token = "_%s" % Var._id # type: ignore[assignment]
  12. Var._id += 1
  13. elif len(token) == 1:
  14. token = token[0]
  15. obj = object.__new__(cls)
  16. obj.token = token # type: ignore[attr-defined]
  17. return obj
  18. def __str__(self):
  19. return "~" + str(self.token) # type: ignore[attr-defined]
  20. __repr__ = __str__
  21. def __eq__(self, other):
  22. return type(self) == type(other) and self.token == other.token # type: ignore[attr-defined]
  23. def __hash__(self):
  24. return hash((type(self), self.token)) # type: ignore[attr-defined]
  25. def var():
  26. return lambda *args: Var(*args)
  27. def vars():
  28. return lambda n: [var() for i in range(n)]
  29. @dispatch(Var)
  30. def isvar(v):
  31. return True
  32. isvar
  33. @dispatch(object) # type: ignore[no-redef]
  34. def isvar(o):
  35. return not not _glv and hashable(o) and o in _glv
  36. @contextmanager
  37. def variables(*variables):
  38. """
  39. Context manager for logic variables
  40. Example:
  41. >>> # xdoctest: +SKIP("undefined vars")
  42. >>> from __future__ import with_statement
  43. >>> with variables(1):
  44. ... print(isvar(1))
  45. True
  46. >>> print(isvar(1))
  47. False
  48. >>> # Normal approach
  49. >>> from unification import unify
  50. >>> x = var('x')
  51. >>> unify(x, 1)
  52. {~x: 1}
  53. >>> # Context Manager approach
  54. >>> with variables('x'):
  55. ... print(unify('x', 1))
  56. {'x': 1}
  57. """
  58. old_global_logic_variables = _global_logic_variables.copy()
  59. _global_logic_variables.update(set(variables))
  60. try:
  61. yield
  62. finally:
  63. _global_logic_variables.clear()
  64. _global_logic_variables.update(old_global_logic_variables)