# Path: prolog/interpreter/error.py
# class UnificationFailed(PrologError):
#     pass
# 
# Path: prolog/interpreter/error.py
# class PrologError(Exception):
# class UncatchableError(PrologError):
# class PrologParseError(PrologError):
# class TermedError(PrologError):
# class CatchableError(TermedError): pass
# class UncaughtError(TermedError):
# class TraceFrame(object):
# class UnificationFailed(PrologError):
#     def __init__(self, message):
#     def __init__(self, file_name, line_number, message):
#     def __init__(self, term, sig_context=None):
#     def get_errstr(self, engine):
#     def __init__(self, term, sig_context=None, rule_likely_source=None, scont=None):
#     def format_traceback(self, engine):
#     def __init__(self, rule, next=None):
#     def __repr__(self):
#     def _format(self, out):
# def _construct_traceback(scont):
# def wrap_error(t):
# def throw_syntax_error(msg):
# def throw_import_error(modulename, signature):
# def throw_existence_error(object_type, obj):
# def throw_instantiation_error(obj = None):
# def throw_representation_error(signature, msg):
# def throw_type_error(valid_type, obj):
# def throw_domain_error(valid_domain, obj):
# def throw_permission_error(operation, permission_type, obj):
# def throw_evaluation_error(error):
# 
# Path: prolog/interpreter/signature.py
# class Signature(object):
#     """An object representing the signature of a Prolog term."""
# 
#     _cache = SignatureFactory()
# 
#     _immutable_fields_ = ["name", "numargs", "atom_signature", "factory"]
# 
#     def __init__(self, name, numargs, cached=False, factory=None):
#         assert name is not None
#         assert isinstance(name, str)
#         name = rstring.assert_str0(name)
#         self.name = name
#         self.numargs = numargs
#         self.cached = cached
#         if factory is None:
#             factory = self._cache
#         self.factory = factory
#         if numargs:
#             atom_signature = factory.getsignature(name, 0, cached)
#         else:
#             atom_signature = self
#         self.atom_signature = atom_signature
#         factory.init_extra_attrs(self)
# 
#     def eq(self, other):
#         # slightly evil
#         if jit.isconstant(self):
#             jit.promote(other)
#         elif jit.isconstant(other):
#             jit.promote(self)
#         return self is other or (
#                 self.numargs == other.numargs and
#                 self.name == other.name)
# 
#     @specialize.arg(1)
#     def get_extra(self, name):
#         aname = "extra_attr_" + name
#         if not we_are_translated():
#             assert aname in self.factory.extra_attr_names
#         self = self.ensure_cached()
#         return getattr(self, aname)
# 
#     @specialize.arg(1)
#     def set_extra(self, name, val):
#         aname = "extra_attr_" + name
#         if not we_are_translated():
#             assert aname in self.factory.extra_attr_names
#         self = self.ensure_cached()
#         setattr(self, aname, val)
# 
# 
#     @specialize.arg(1)
#     def get_extra_engine_local(self, name, engine):
#         ename = "extra_attr_engine_" + name
#         if not we_are_translated():
#             assert ename in self.factory.extra_attr_names
#         if getattr(self, ename) is not engine:
#             setattr(self, ename, engine)
#             aname = "extra_attr_" + name
#             setattr(self, aname, None)    
#         return self.get_extra(name)
# 
#     @specialize.arg(1)
#     def set_extra_engine_local(self, name, val, engine):
#         ename = "extra_attr_engine_" + name
#         setattr(self, ename, engine)
#         self.set_extra(name, val)
# 
#     def ensure_cached(self):
#         if self.cached:
#             return self
#         return self.factory.ensure_cached(self)
# 
#     def string(self):
#         return "%s/%s" % (self.name, self.numargs)
# 
#     def __repr__(self):
#         return "<Signature %s>" % (self.string(), )
# 
#     @staticmethod
#     @jit.elidable
#     def getsignature(name, numargs):
#         return Signature._cache.getsignature(name, numargs)
# 
#     @staticmethod
#     def register_extr_attr(name, engine=False, default=None):
#         Signature._cache.register_extr_attr(name, engine, default)


import math
from prolog.interpreter.error import UnificationFailed
from prolog.interpreter import error
from prolog.interpreter.signature import Signature
from rpython.rlib.objectmodel import we_are_translated, UnboxedValue
from rpython.rlib.objectmodel import compute_unique_id
from rpython.rlib.objectmodel import specialize
from rpython.rlib.debug import make_sure_not_resized
from rpython.rlib import jit, debug
from rpython.tool.pairtype import extendabletype
from rpython.rlib.rbigint import rbigint
        from prolog.interpreter.arithmetic import get_arithmetic_function
    from rpython.rlib.unroll import unrolling_iterable
    from rpython.rlib.unroll import unrolling_iterable
    
    def __init__(self, name, signature=None):
        if signature is None:
            signature = Signature(name, 0)
        Callable.__init__(self)
        self._signature = signature
    
    def __str__(self):
        return self.name()
    
    def __repr__(self):
        return "Atom(%r)" % (self.name(),)
    
    @staticmethod
    @jit.elidable
    def newatom(name, signature=None):
        if signature is None:
            signature = Signature.getsignature(name, 0)
        result = Atom.cache.get(signature, None)
        if result is not None:
            return result
        Atom.cache[signature] = result = Atom(name, signature)
        return result
    
    def eval_arithmetic(self, engine):
        #XXX beautify that
        if self.name() == "pi":
            return Float.pi
        if self.name() == "e":
            return Float.e

# Path: prolog/interpreter/error.py
# class UnificationFailed(PrologError):
#     pass
# 
# Path: prolog/interpreter/error.py
# class PrologError(Exception):
# class UncatchableError(PrologError):
# class PrologParseError(PrologError):
# class TermedError(PrologError):
# class CatchableError(TermedError): pass
# class UncaughtError(TermedError):
# class TraceFrame(object):
# class UnificationFailed(PrologError):
#     def __init__(self, message):
#     def __init__(self, file_name, line_number, message):
#     def __init__(self, term, sig_context=None):
#     def get_errstr(self, engine):
#     def __init__(self, term, sig_context=None, rule_likely_source=None, scont=None):
#     def format_traceback(self, engine):
#     def __init__(self, rule, next=None):
#     def __repr__(self):
#     def _format(self, out):
# def _construct_traceback(scont):
# def wrap_error(t):
# def throw_syntax_error(msg):
# def throw_import_error(modulename, signature):
# def throw_existence_error(object_type, obj):
# def throw_instantiation_error(obj = None):
# def throw_representation_error(signature, msg):
# def throw_type_error(valid_type, obj):
# def throw_domain_error(valid_domain, obj):
# def throw_permission_error(operation, permission_type, obj):
# def throw_evaluation_error(error):
# 
# Path: prolog/interpreter/signature.py
# class Signature(object):
#     """An object representing the signature of a Prolog term."""
# 
#     _cache = SignatureFactory()
# 
#     _immutable_fields_ = ["name", "numargs", "atom_signature", "factory"]
# 
#     def __init__(self, name, numargs, cached=False, factory=None):
#         assert name is not None
#         assert isinstance(name, str)
#         name = rstring.assert_str0(name)
#         self.name = name
#         self.numargs = numargs
#         self.cached = cached
#         if factory is None:
#             factory = self._cache
#         self.factory = factory
#         if numargs:
#             atom_signature = factory.getsignature(name, 0, cached)
#         else:
#             atom_signature = self
#         self.atom_signature = atom_signature
#         factory.init_extra_attrs(self)
# 
#     def eq(self, other):
#         # slightly evil
#         if jit.isconstant(self):
#             jit.promote(other)
#         elif jit.isconstant(other):
#             jit.promote(self)
#         return self is other or (
#                 self.numargs == other.numargs and
#                 self.name == other.name)
# 
#     @specialize.arg(1)
#     def get_extra(self, name):
#         aname = "extra_attr_" + name
#         if not we_are_translated():
#             assert aname in self.factory.extra_attr_names
#         self = self.ensure_cached()
#         return getattr(self, aname)
# 
#     @specialize.arg(1)
#     def set_extra(self, name, val):
#         aname = "extra_attr_" + name
#         if not we_are_translated():
#             assert aname in self.factory.extra_attr_names
#         self = self.ensure_cached()
#         setattr(self, aname, val)
# 
# 
#     @specialize.arg(1)
#     def get_extra_engine_local(self, name, engine):
#         ename = "extra_attr_engine_" + name
#         if not we_are_translated():
#             assert ename in self.factory.extra_attr_names
#         if getattr(self, ename) is not engine:
#             setattr(self, ename, engine)
#             aname = "extra_attr_" + name
#             setattr(self, aname, None)    
#         return self.get_extra(name)
# 
#     @specialize.arg(1)
#     def set_extra_engine_local(self, name, val, engine):
#         ename = "extra_attr_engine_" + name
#         setattr(self, ename, engine)
#         self.set_extra(name, val)
# 
#     def ensure_cached(self):
#         if self.cached:
#             return self
#         return self.factory.ensure_cached(self)
# 
#     def string(self):
#         return "%s/%s" % (self.name, self.numargs)
# 
#     def __repr__(self):
#         return "<Signature %s>" % (self.string(), )
# 
#     @staticmethod
#     @jit.elidable
#     def getsignature(name, numargs):
#         return Signature._cache.getsignature(name, numargs)
# 
#     @staticmethod
#     def register_extr_attr(name, engine=False, default=None):
#         Signature._cache.register_extr_attr(name, engine, default)


# Path: prolog/interpreter/term.py
import math
from prolog.interpreter.error import UnificationFailed
from prolog.interpreter import error
from prolog.interpreter.signature import Signature
from rpython.rlib.objectmodel import we_are_translated, UnboxedValue
from rpython.rlib.objectmodel import compute_unique_id
from rpython.rlib.objectmodel import specialize
from rpython.rlib.debug import make_sure_not_resized
from rpython.rlib import jit, debug
from rpython.tool.pairtype import extendabletype
from rpython.rlib.rbigint import rbigint
        from prolog.interpreter.arithmetic import get_arithmetic_function
    from rpython.rlib.unroll import unrolling_iterable
    from rpython.rlib.unroll import unrolling_iterable

    
    def __init__(self, name, signature=None):
        if signature is None:
            signature = Signature(name, 0)
        Callable.__init__(self)
        self._signature = signature
    
    def __str__(self):
        return self.name()
    
    def __repr__(self):
        return "Atom(%r)" % (self.name(),)
    
    @staticmethod
    @jit.elidable
    def newatom(name, signature=None):
        if signature is None:
            signature = Signature.getsignature(name, 0)
        result = Atom.cache.get(signature, None)
        if result is not None:
            return result
        Atom.cache[signature] = result = Atom(name, signature)
        return result
    
    def eval_arithmetic(self, engine):
        #XXX beautify that
        if self.name() == "pi":
            return Float.pi
        if self.name() == "e":
            return Float.e

        error.throw_type_error("evaluable", self.get_prolog_signature())