variable.py 2.0 KB

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