| | from contextlib import contextmanager |
| | from .utils import hashable |
| | from .dispatch import dispatch |
| |
|
| | _global_logic_variables = set() |
| | _glv = _global_logic_variables |
| |
|
| |
|
| | class Var(object): |
| | """ Logic Variable """ |
| |
|
| | _id = 1 |
| |
|
| | def __new__(cls, *token): |
| | if len(token) == 0: |
| | token = "_%s" % Var._id |
| | Var._id += 1 |
| | elif len(token) == 1: |
| | token = token[0] |
| |
|
| | obj = object.__new__(cls) |
| | obj.token = token |
| | return obj |
| |
|
| | def __str__(self): |
| | return "~" + str(self.token) |
| | __repr__ = __str__ |
| |
|
| | def __eq__(self, other): |
| | return type(self) == type(other) and self.token == other.token |
| |
|
| | def __hash__(self): |
| | return hash((type(self), self.token)) |
| |
|
| |
|
| | def var(): |
| | return lambda *args: Var(*args) |
| |
|
| | def vars(): |
| | return lambda n: [var() for i in range(n)] |
| |
|
| |
|
| | @dispatch(Var) |
| | def isvar(v): |
| | return True |
| |
|
| | isvar |
| |
|
| | @dispatch(object) |
| | def isvar(o): |
| | return not not _glv and hashable(o) and o in _glv |
| |
|
| |
|
| | @contextmanager |
| | def variables(*variables): |
| | """ Context manager for logic variables |
| | >>> from __future__ import with_statement |
| | >>> with variables(1): |
| | ... print(isvar(1)) |
| | True |
| | >>> print(isvar(1)) |
| | False |
| | >>> # xdoctest: +SKIP("undefined vars") |
| | >>> # Normal approach |
| | >>> from unification import unify |
| | >>> x = var('x') |
| | >>> unify(x, 1) |
| | {~x: 1} |
| | >>> # Context Manager approach |
| | >>> with variables('x'): |
| | ... print(unify('x', 1)) |
| | {'x': 1} |
| | """ |
| | old_global_logic_variables = _global_logic_variables.copy() |
| | _global_logic_variables.update(set(variables)) |
| | try: |
| | yield |
| | finally: |
| | _global_logic_variables.clear() |
| | _global_logic_variables.update(old_global_logic_variables) |
| |
|