コード例 #1
0
ファイル: test_parsing.py プロジェクト: cosmoharrigan/pyrolog
def test_numeral():
    from prolog.interpreter.term import Callable, Atom, BindingVar
    from prolog.interpreter.continuation import Engine
    t = parse_file("""
numeral(null). % end of line comment
numeral(succ(X)) :- numeral(X). % another one

add_numeral(X, null, X).
add_numeral(X, succ(Y), Z) :- add_numeral(succ(X), Y, Z).

greater_than(succ(null), null).
greater_than(succ(X), null) :- greater_than(X, null).
greater_than(succ(X), succ(Y)) :- greater_than(X, Y).
""")
    builder = TermBuilder()
    facts = builder.build(t)
    e = Engine()
    m = e.modulewrapper
    for fact in facts:
        print fact
        e.add_rule(fact)
    assert m.modules["user"].lookup(Signature.getsignature("add_numeral", 3)).rulechain.head.argument_at(1).name() == "null"
    four = Callable.build("succ", [Callable.build("succ", [Callable.build("succ",
                [Callable.build("succ", [Callable.build("null")])])])])
    e.run_query_in_current(parse_query_term("numeral(succ(succ(null)))."))
    term = parse_query_term(
        """add_numeral(succ(succ(null)), succ(succ(null)), X).""")
    e.run_query_in_current(term)
    hp = Heap()
    var = BindingVar().dereference(hp)
    # does not raise
    var.unify(four, hp)
    term = parse_query_term(
        """greater_than(succ(succ(succ(null))), succ(succ(null))).""")
    e.run_query_in_current(term)
コード例 #2
0
def get_rules_from_fact(engine, rule, rule_dist, query, heap, rules = None):
    module = engine.modulewrapper.current_module 
    rule = rule.split('/')
    name = rule[0]
    nargs = int(rule[1])
    sig = Signature.getsignature(name, nargs)
    function = module.lookup(sig)
    simchain = []
    if (function.rulechain is None):
        return None #handle by UnificationFailed
    if rules is None:
        rules = []
    #engine._print_rulechain(function.rulechain)
    #print('\n')
    startrulechain = jit.hint(function.rulechain, promote = True)
    if startrulechain is not None:
        rulechain, simchain = startrulechain.find_applicable_rule(query, heap, engine.similarity, simchain, module, nargs) # TODO similarity
        while rulechain is not None:
            rules.append(jit.hint(rulechain, promote = True)) 
            rulechain, simchain = rulechain.find_next_applicable_rule(query, heap, engine.similarity, simchain, module, nargs)
    
     

    #print(rules)
    return rules
コード例 #3
0
ファイル: test_error.py プロジェクト: sebdumancic/pyrolog
def test_traceback_in_if():
    e = get_engine("""
        h(y).
        g(a).
        g(_) :- throw(foo).
        f(X, Y) :- (g(X) -> X = 1 ; X = 2), h(Y).
    """)
    error = get_uncaught_error("f(1, Y).", e)
    sig_g = Signature.getsignature("g", 1)
    sig_f = Signature.getsignature("f", 2)
    m = e.modulewrapper
    rule_f = m.user_module.lookup(sig_f).rulechain
    rule_g = m.user_module.lookup(sig_g).rulechain.next
    tb = error.traceback
    assert tb.rule is rule_f
    assert tb.next.rule is rule_g
コード例 #4
0
    def build(term_name, args=None, signature=None, heap=None, cache=True):
        if args is None:
            args = []
        if heap is not None:
            # perform variable shunting:
            # remove variables that are not needed because they are bound
            # already and cannot be backtracked
            for i in range(len(args)):
                arg = args[i]
                if (isinstance(arg, Var) and arg.getbinding() is not None and
                        arg.created_after_choice_point is heap):
                    args[i] = arg.getbinding()
        if len(args) == 0:
            if cache:
                return Atom.newatom(term_name, signature)
            return Atom(term_name, signature)
        else:
            if signature is None:
                if cache:
                    signature = Signature.getsignature(term_name, len(args))
                else:
                    signature = Signature(term_name, len(args))
            else:
                assert signature.numargs == len(args)
            assert isinstance(signature, Signature)

            cls = Callable._find_specialized_class(term_name, len(args))
            if cls is not None:
                return cls(term_name, args, signature)
            cls = Callable._find_specialized_class('Term', len(args))
            if cls is not None:
                return cls(term_name, args, signature)
            return Term(term_name, args, signature)
コード例 #5
0
ファイル: test_error.py プロジェクト: cosmoharrigan/pyrolog
def test_traceback_in_if():
    e = get_engine("""
        h(y).
        g(a).
        g(_) :- throw(foo).
        f(X, Y) :- (g(X) -> X = 1 ; X = 2), h(Y).
    """)
    error = get_uncaught_error("f(1, Y).", e)
    sig_g = Signature.getsignature("g", 1)
    sig_f = Signature.getsignature("f", 2)
    m = e.modulewrapper
    rule_f = m.user_module.lookup(sig_f).rulechain
    rule_g = m.user_module.lookup(sig_g).rulechain.next
    tb = error.traceback
    assert tb.rule is rule_f
    assert tb.next.rule is rule_g
コード例 #6
0
def generate_class(cname, fname, n_args):
    from rpython.rlib.unroll import unrolling_iterable
    arg_iter = unrolling_iterable(range(n_args))
    parent = callables['Abstract', n_args]
    assert parent is not None
    signature = Signature.getsignature(fname, n_args)

    class specific_class(parent):
        if n_args == 0:
            TYPE_STANDARD_ORDER = Atom.TYPE_STANDARD_ORDER
        else:
            TYPE_STANDARD_ORDER = Term.TYPE_STANDARD_ORDER

        def __init__(self, term_name, args, signature):
            parent._init_values(self, args)
            assert self.name() == term_name
            assert args is None or len(args) == n_args

        def name(self):
            return fname

        def signature(self):
            return signature

        def _make_new(self, name, signature):
            cls = specific_class
            return cls(name, None, signature)

    specific_class.__name__ = cname
    return specific_class
コード例 #7
0
ファイル: reasoning.py プロジェクト: hellozhaojian/CORGI
def isFactInKB(factPredicate, factArgs, factQuery, prolog, predicateDict):
    sig = Signature.getsignature(str(factPredicate), len(factArgs))
    isBuiltin = prolog.get_builtin(sig)
    assert (not isBuiltin), 'we should have already checked this'

    factInKB = False

    query = '{0}({1}).'.format(
        factPredicate,
        ','.join(['X_{0}'.format(i) for i in range(len(factArgs))]))
    if prologPath == '/testnet' or prologPath == '/proofspyrolog':
        proof = collect_all(prolog, query, [], [], [], [])
    elif prologPath == '/spyrolog':
        proof = collect_all(prolog, query, [], [], [])

    for vGrounding in proof:
        groundings = vGrounding[0]
        args = set()
        for variable, grounding in groundings.iteritems():
            if hasattr(grounding, 'name'):
                args.add(grounding.name())
            elif hasattr(grounding, 'num'):
                args.add(grounding.num)
            else:
                print 'dir:', dir(grounding)
                raise AttributeError

        if not set(factArgs).difference(args):
            factInKB = True
            break

    return factInKB
コード例 #8
0
ファイル: term.py プロジェクト: cosmoharrigan/pyrolog
    def build(term_name, args=None, signature=None, heap=None, cache=True):
        if args is None:
            args = []
        if heap is not None:
            # perform variable shunting:
            # remove variables that are not needed because they are bound
            # already and cannot be backtracked
            for i in range(len(args)):
                arg = args[i]
                if (isinstance(arg, Var) and arg.getbinding() is not None and
                        arg.created_after_choice_point is heap):
                    args[i] = arg.getbinding()
        if len(args) == 0:
            if cache:
                return Atom.newatom(term_name, signature)
            return Atom(term_name, signature)
        else:
            if signature is None:
                if cache:
                    signature = Signature.getsignature(term_name, len(args))
                else:
                    signature = Signature(term_name, len(args))
            else:
                assert signature.numargs == len(args)
            assert isinstance(signature, Signature)

            cls = Callable._find_specialized_class(term_name, len(args))
            if cls is not None:
                return cls(term_name, args, signature)
            cls = Callable._find_specialized_class('Term', len(args))
            if cls is not None:
                return cls(term_name, args, signature)
            return Term(term_name, args, signature)
コード例 #9
0
ファイル: term.py プロジェクト: cosmoharrigan/pyrolog
 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
コード例 #10
0
ファイル: module.py プロジェクト: cosmoharrigan/pyrolog
 def add_module(self, name, exports = []):
     mod = Module(name)
     for export in exports:
         mod.exports.append(Signature.getsignature(
                 *unwrap_predicate_indicator(export)))
     self.current_module = mod
     self.modules[name] = mod
     self.version = VersionTag()
コード例 #11
0
 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
コード例 #12
0
 def add_module(self, name, exports=[]):
     mod = Module(name)
     for export in exports:
         mod.exports.append(
             Signature.getsignature(*unwrap_predicate_indicator(export)))
     self.current_module = mod
     self.modules[name] = mod
     self.version = VersionTag()
コード例 #13
0
ファイル: modules.py プロジェクト: cosmoharrigan/pyrolog
def impl_use_module_with_importlist(engine, heap, module, path, imports):
    importlist = []
    for sigatom in imports:
        importlist.append(Signature.getsignature(
                *unwrap_predicate_indicator(sigatom))) 
    if isinstance(path, Atom):
        handle_use_module(engine, heap, module, path, importlist)
    else:
        handle_use_module_with_library(engine, heap, module, path, importlist)
コード例 #14
0
def impl_use_module_with_importlist(engine, heap, module, path, imports):
    importlist = []
    for sigatom in imports:
        importlist.append(
            Signature.getsignature(*unwrap_predicate_indicator(sigatom)))
    if isinstance(path, Atom):
        handle_use_module(engine, heap, module, path, importlist)
    else:
        handle_use_module_with_library(engine, heap, module, path, importlist)
コード例 #15
0
def test_lookup():
    e = get_engine("""
    :- use_module(m).
    f(a) :- g(a, b).
    """,
                   m="""
    :- module(m, [g/2]).
    g(a, b).
    h(w).
    """)
    f_sig = Signature.getsignature("f", 1)
    g_sig = Signature.getsignature("g", 2)
    h_sig = Signature.getsignature("h", 1)
    user = e.modulewrapper.modules["user"]
    m = e.modulewrapper.modules["m"]

    assert user.lookup(g_sig) == m.functions[g_sig]
    assert user.lookup(h_sig).rulechain is None
    assert m.lookup(g_sig) == m.functions[g_sig]
    assert m.lookup(f_sig).rulechain is None
    assert m.lookup(h_sig) == m.functions[h_sig]
コード例 #16
0
ファイル: test_module.py プロジェクト: cosmoharrigan/pyrolog
def test_lookup():
    e = get_engine("""
    :- use_module(m).
    f(a) :- g(a, b).
    """,
    m = """
    :- module(m, [g/2]).
    g(a, b).
    h(w).
    """)
    f_sig = Signature.getsignature("f", 1)
    g_sig = Signature.getsignature("g", 2)
    h_sig = Signature.getsignature("h", 1)
    user = e.modulewrapper.modules["user"]
    m = e.modulewrapper.modules["m"]

    assert user.lookup(g_sig) == m.functions[g_sig]
    assert user.lookup(h_sig).rulechain is None
    assert m.lookup(g_sig) == m.functions[g_sig]
    assert m.lookup(f_sig).rulechain is None
    assert m.lookup(h_sig) == m.functions[h_sig]
コード例 #17
0
ファイル: test_function.py プロジェクト: sebdumancic/pyrolog
def test_discard_useless_env_suffix():
    e = get_engine("""
        f(h(A), A, B, C) :- g(B), h(D), h1(D), h(E).
    """)
    # classes of variables:
    # just in head: A    (needs index at the end of env)
    # both: B            (needs index at the beginning of env)
    # singletons head: C (-1)
    # singletons body: E (-1, XXX currently not optimized)
    # just in body: D    (needs index at end of env, appended after matching head)
    func = e.modulewrapper.current_module.lookup(Signature.getsignature(
        "f", 4))
コード例 #18
0
def test_source_range():
    e = get_engine("""
f(a) :- a.
f(b) :-
    b.
a.
b.
""")
    func = e.modulewrapper.current_module.lookup(Signature.getsignature("f", 1))
    assert func.rulechain.line_range == [1, 2]
    assert func.rulechain.next.line_range == [2, 4]
    assert func.rulechain.file_name == "<unknown>"
    assert func.rulechain.source == "f(a) :- a."
    assert func.rulechain.next.source == "f(b) :-\n    b."
コード例 #19
0
ファイル: test_function.py プロジェクト: sebdumancic/pyrolog
def test_source_range():
    e = get_engine("""
f(a) :- a.
f(b) :-
    b.
a.
b.
""")
    func = e.modulewrapper.current_module.lookup(Signature.getsignature(
        "f", 1))
    assert func.rulechain.line_range == [1, 2]
    assert func.rulechain.next.line_range == [2, 4]
    assert func.rulechain.file_name == "<unknown>"
    assert func.rulechain.source == "f(a) :- a."
    assert func.rulechain.next.source == "f(b) :-\n    b."
コード例 #20
0
def impl_abolish(engine, heap, module, predicate):
    modname = None
    if predicate.signature().eq(prefixsig):
        modname, predicate = unpack_modname_and_predicate(predicate)
    name, arity = helper.unwrap_predicate_indicator(predicate)
    if arity < 0:
        error.throw_domain_error("not_less_than_zero", term.Number(arity))
    signature = Signature.getsignature(name, arity)
    if signature.get_extra("builtin"):
        error.throw_permission_error("modify", "static_procedure", predicate)
    if modname is not None:
        module = engine.modulewrapper.get_module(modname, predicate)
    try:
        del module.functions[signature]
    except KeyError:
        pass
コード例 #21
0
ファイル: database.py プロジェクト: cosmoharrigan/pyrolog
def impl_abolish(engine, heap, module, predicate):
    modname = None
    if predicate.signature().eq(prefixsig):
        modname, predicate = unpack_modname_and_predicate(predicate)
    name, arity = helper.unwrap_predicate_indicator(predicate)
    if arity < 0:
        error.throw_domain_error("not_less_than_zero", term.Number(arity))
    signature = Signature.getsignature(name, arity)
    if signature.get_extra("builtin"):
        error.throw_permission_error("modify", "static_procedure",
                                     predicate)
    if modname is not None:
        module = engine.modulewrapper.get_module(modname, predicate)
    try:
        del module.functions[signature]
    except KeyError:
        pass
コード例 #22
0
ファイル: function.py プロジェクト: hellozhaojian/CORGI
    def find_applicable_rule(self,
                             query,
                             heap=None,
                             similarity=None,
                             simchain=[],
                             module=None,
                             nargs=0):
        # This method should do some quick filtering on the rules to filter out
        # those that cannot match query. Here is where e.g. indexing should
        # occur.
        while ((self is not None) or (simchain != [])):
            #print "Entering loop", self, "simchain", simchain
            # if self is None go to next rule in simchain
            if (self == None):
                #print("Moving to next rulechain in simchain...")
                name = simchain[0]
                simchain = simchain[1:]
                signature = Signature.getsignature(name, nargs)
                function = module.lookup(signature)
                self = function.rulechain
                if (self == None):
                    continue

            #print(self.scores[0] * heap.predicate_score)
            #print(similarity.threshold)
            if (self.scores[0] * heap.predicate_score >= similarity.threshold):
                if self.headargs is not None:
                    if (len(self.headargs) != query.argument_count()):
                        self = self.next
                        continue
                    assert isinstance(query, Callable)
                    for i in range(len(self.headargs)):
                        arg2 = self.headargs[i]
                        arg1 = query.argument_at(i)
                        if not arg2.quick_unify_check(arg1,
                                                      similarity=similarity):
                            break
                    else:
                        return self, simchain
                else:
                    return self, simchain
            self = self.next
        return None, []
コード例 #23
0
ファイル: term.py プロジェクト: cosmoharrigan/pyrolog
def generate_class(cname, fname, n_args, immutable=True):
    from rpython.rlib.unroll import unrolling_iterable
    arg_iter = unrolling_iterable(range(n_args))
    parent = callables['Abstract', n_args]
    if not immutable:
        parent = parent.mutable_version
    assert parent is not None
    signature = Signature.getsignature(fname, n_args)

    class specific_class(parent):
        if n_args == 0:
            TYPE_STANDARD_ORDER = Atom.TYPE_STANDARD_ORDER
        else:
            TYPE_STANDARD_ORDER = Term.TYPE_STANDARD_ORDER
        
        def __init__(self, term_name, args, signature):
            parent._init_values(self, args)
            assert self.name() == term_name
            assert args is None or len(args) == n_args
                
        def name(self):
            return fname
        
        def signature(self):
            return signature

        def _make_new(self, name, signature):
            cls = specific_class
            return cls(name, None, signature)

        if immutable:
            def _make_new_mutable(self, name, signature):
                cls = mutable_version
                return cls(name, None, signature)
        else:
            _make_new_mutable = _make_new
    if immutable:
        mutable_version = specific_class.mutable_version = generate_class(
                cname, fname, n_args, False)
    specific_class.__name__ = cname + "Mutable" * (not immutable)
    return specific_class
コード例 #24
0
def test_numeral():
    from prolog.interpreter.term import Callable, Atom, BindingVar
    from prolog.interpreter.continuation import Engine
    t = parse_file("""
numeral(null). % end of line comment
numeral(succ(X)) :- numeral(X). % another one

add_numeral(X, null, X).
add_numeral(X, succ(Y), Z) :- add_numeral(succ(X), Y, Z).

greater_than(succ(null), null).
greater_than(succ(X), null) :- greater_than(X, null).
greater_than(succ(X), succ(Y)) :- greater_than(X, Y).
""")
    builder = TermBuilder()
    facts = builder.build(t)
    e = Engine()
    m = e.modulewrapper
    for fact in facts:
        print fact
        e.add_rule(fact)
    assert m.modules["user"].lookup(Signature.getsignature(
        "add_numeral", 3)).rulechain.head.argument_at(1).name() == "null"
    four = Callable.build("succ", [
        Callable.build("succ", [
            Callable.build("succ",
                           [Callable.build("succ", [Callable.build("null")])])
        ])
    ])
    e.run_query_in_current(parse_query_term("numeral(succ(succ(null)))."))
    term = parse_query_term(
        """add_numeral(succ(succ(null)), succ(succ(null)), X).""")
    e.run_query_in_current(term)
    hp = Heap()
    var = BindingVar().dereference(hp)
    # does not raise
    var.unify(four, hp)
    term = parse_query_term(
        """greater_than(succ(succ(succ(null))), succ(succ(null))).""")
    e.run_query_in_current(term)
コード例 #25
0
ファイル: function.py プロジェクト: hellozhaojian/CORGI
 def find_next_applicable_rule(self,
                               query,
                               heap=None,
                               similarity=None,
                               simchain=[],
                               module=None,
                               nargs=0):
     self = self.next
     if self is None:
         while (simchain != []):
             #print("Moving to next rulechain in simchain...")
             name = simchain[0]
             simchain = simchain[1:]
             signature = Signature.getsignature(name, nargs)
             function = module.lookup(signature)
             self = function.rulechain
             if (self is not None):
                 return self.find_applicable_rule(query, heap, similarity,
                                                  simchain, module, nargs)
         return None, []
     return self.find_applicable_rule(query, heap, similarity, simchain,
                                      module, nargs)
コード例 #26
0
ファイル: helper.py プロジェクト: cosmoharrigan/pyrolog
""" Helper functions for dealing with prolog terms"""

from prolog.interpreter import term
from prolog.interpreter import error
from prolog.interpreter.signature import Signature
from rpython.rlib import jit
from prolog.interpreter.stream import PrologOutputStream, PrologInputStream,\
        PrologStream

conssig = Signature.getsignature(".", 2)
nilsig = Signature.getsignature("[]", 0)

emptylist = term.Callable.build("[]")

def wrap_list(python_list):
    curr = emptylist
    for i in range(len(python_list) - 1, -1, -1):
        curr = term.Callable.build(".", [python_list[i], curr])
    return curr

@jit.unroll_safe
def unwrap_list(prolog_list):
    # Grrr, stupid JIT
    result = [None]
    used = 0
    curr = prolog_list
    while isinstance(curr, term.Callable) and curr.signature().eq(conssig):
        if used == len(result):
            nresult = [None] * (used * 2)
            for i in range(used):
                nresult[i] = result[i]
コード例 #27
0
ファイル: test_error.py プロジェクト: cosmoharrigan/pyrolog
def test_exception_knows_builtin_signature():
    e = get_engine("""
        f(X, Y) :- atom_length(X, Y).
    """)
    error = get_uncaught_error("f(1, Y).", e)
    assert error.sig_context == Signature.getsignature("atom_length", 2)
コード例 #28
0
ファイル: arithmetic.py プロジェクト: sebdumancic/pyrolog
    ("mod", 2, "mod"),
    ("\\", 1, "not"),
    ("abs", 1, "abs"),
    ("max", 2, "max"),
    ("min", 2, "min"),
    ("round", 1, "round"),
    ("floor", 1, "floor"), #XXX
    ("ceiling", 1, "ceiling"), #XXX
    ("float_fractional_part", 1, "float_fractional_part"), #XXX
    ("float_integer_part", 1, "float_integer_part")
]

for prolog_name, num_args, name in simple_functions:
    f = wrap_builtin_operation(name, num_args)
    
    signature = Signature.getsignature(prolog_name, num_args)
    signature.set_extra("arithmetic", f)

    for suffix in ["", "_number", "_bigint", "_float"]:
        def not_implemented_func(*args):
            raise NotImplementedError("abstract base class")
        setattr(term.Numeric, "arith_%s%s" % (name, suffix), not_implemented_func)

@jit.elidable_promote('all')
def get_arithmetic_function(signature):
    return signature.get_extra("arithmetic")

def make_int(w_value):
    if isinstance(w_value, term.BigInt):
        try:
            num = w_value.value.toint()
コード例 #29
0
ファイル: control.py プロジェクト: hellozhaojian/CORGI
from prolog.interpreter import helper, term, error, continuation
from prolog.builtin.register import expose_builtin
from prolog.interpreter.signature import Signature

ifsig = Signature.getsignature("->", 2)
cutsig = Signature.getsignature("!", 0)
FAILATOM = term.Callable.build("fail")
TRUEATOM = term.Callable.build("true")

# ___________________________________________________________________
# control predicates

@expose_builtin("fail", unwrap_spec=[])
def impl_fail(engine, heap):
    raise error.UnificationFailed()

@expose_builtin("true", unwrap_spec=[])
def impl_true(engine, heap):
    return

@expose_builtin("repeat", unwrap_spec=[], handles_continuation=True)
def impl_repeat(engine, heap, scont, fcont):
    return scont, RepeatContinuation(engine, scont, fcont, heap), heap.branch()

class RepeatContinuation(continuation.FailureContinuation):
    def fail(self, heap):
        heap = heap.revert_upto(self.undoheap)
        return self.nextcont, self, heap

@expose_builtin("!", unwrap_spec=[], handles_continuation=True)
def impl_cut(engine, heap, scont, fcont):
コード例 #30
0
ファイル: continuation.py プロジェクト: cosmoharrigan/pyrolog
def get_printable_location(rule, sconttype):
    if rule:
        s = rule.signature.string()
    else:
        s = "No rule"
    return "%s %s" % (s, sconttype)

def get_jitcell_at(where, rule):
    # XXX can be vastly simplified
    return rule.jit_cells.get(where, None)

def set_jitcell_at(newcell, where, rule):
    # XXX can be vastly simplified
    rule.jit_cells[where] = newcell

predsig = Signature.getsignature(":-", 2)
callsig = Signature.getsignature(":-", 1)

jitdriver = jit.JitDriver(
        greens=["rule", "sconttype"],
        reds=["scont", "fcont", "heap"],
        get_printable_location=get_printable_location,
        #get_jitcell_at=get_jitcell_at,
        #set_jitcell_at=set_jitcell_at,
        )

# ___________________________________________________________________
# end JIT stuff


def driver(scont, fcont, heap):
コード例 #31
0
""" Helper functions for dealing with prolog terms"""

from prolog.interpreter import term
from prolog.interpreter import error
from prolog.interpreter.signature import Signature
from rpython.rlib import jit
from prolog.interpreter.stream import PrologOutputStream, PrologInputStream,\
        PrologStream

conssig = Signature.getsignature(".", 2)
nilsig = Signature.getsignature("[]", 0)

emptylist = term.Callable.build("[]")


def wrap_list(python_list):
    curr = emptylist
    for i in range(len(python_list) - 1, -1, -1):
        curr = term.Callable.build(".", [python_list[i], curr])
    return curr


@jit.unroll_safe
def unwrap_list(prolog_list):
    # Grrr, stupid JIT
    result = [None]
    used = 0
    curr = prolog_list
    while isinstance(curr, term.Callable) and curr.signature().eq(conssig):
        if used == len(result):
            nresult = [None] * (used * 2)
コード例 #32
0
ファイル: test_error.py プロジェクト: sebdumancic/pyrolog
def test_exception_knows_builtin_signature():
    e = get_engine("""
        f(X, Y) :- atom_length(X, Y).
    """)
    error = get_uncaught_error("f(1, Y).", e)
    assert error.sig_context == Signature.getsignature("atom_length", 2)
コード例 #33
0
    else:
        s = "No rule"
    return "%s %s" % (s, sconttype)


def get_jitcell_at(where, rule):
    # XXX can be vastly simplified
    return rule.jit_cells.get(where, None)


def set_jitcell_at(newcell, where, rule):
    # XXX can be vastly simplified
    rule.jit_cells[where] = newcell


predsig = Signature.getsignature(":-", 2)
callsig = Signature.getsignature(":-", 1)

jitdriver = jit.JitDriver(
    greens=["rule", "sconttype"],
    reds=["scont", "fcont", "heap"],
    get_printable_location=get_printable_location,
    #get_jitcell_at=get_jitcell_at,
    #set_jitcell_at=set_jitcell_at,
)

# ___________________________________________________________________
# end JIT stuff


def driver(scont, fcont, heap, engine):
コード例 #34
0
import os
import string

from prolog.interpreter.term import Float, Number, Var, Atom, Callable, AttVar
from prolog.interpreter import error, helper, parsing
from prolog.builtin.register import expose_builtin
from prolog.interpreter.signature import Signature
from prolog.interpreter.stream import PrologStream

conssig = Signature.getsignature(".", 2)
nilsig = Signature.getsignature("[]", 0)
tuplesig = Signature.getsignature(",", 2)


class TermFormatter(object):
    def __init__(self, engine, quoted=False, max_depth=0,
                 ignore_ops=False):
        self.engine = engine
        self.quoted = quoted
        self.max_depth = max_depth
        self.ignore_ops = ignore_ops
        self.curr_depth = 0
        self._make_reverse_op_mapping()
        self.var_to_number = {}
    
    def from_option_list(engine, options):
        # XXX add numbervars support
        quoted = False
        max_depth = 0
        ignore_ops = False
        number_vars = False
コード例 #35
0
def make_wrapper(func,
                 name,
                 unwrap_spec=[],
                 handles_continuation=False,
                 translatable=True,
                 needs_module=False,
                 needs_rule=False):
    numargs = len(unwrap_spec)
    if isinstance(name, list):
        expose_as = name
        name = name[0]
    else:
        expose_as = [name]
    if not name.isalnum():
        name = func.func_name
    orig_funcargs = inspect.getargs(func.func_code)[0]
    funcname = "wrap_%s_%s" % (name, numargs)
    code = ["def %s(engine, query, rule, scont, fcont, heap):" % (funcname, )]
    code.append("    module = rule.module")
    if not translatable:
        code.append("    if we_are_translated():")
        code.append(
            "        raise error.UncatchableError('%s does not work in translated version')"
            % (name, ))
    subargs = ["engine", "heap"]
    assert orig_funcargs[0] == "engine"
    assert orig_funcargs[1] == "heap"
    code.append("    assert isinstance(query, term.Callable)")
    for i, spec in enumerate(unwrap_spec):
        varname = "var%s" % (i, )
        subargs.append(varname)
        if spec in ("obj", "callable", "int", "atom", "arithmetic", "instream",
                    "outstream", "stream", "list"):
            code.append("    %s = query.argument_at(%s).dereference(heap)" %
                        (varname, i))
        if spec in ("int", "atom", "arithmetic", "list", "instream",
                    "outstream", "stream"):
            code.append("    if isinstance(%s, term.Var):" % (varname, ))
            code.append("        error.throw_instantiation_error()")
        if spec == "obj":
            pass
        elif spec == "callable":
            code.append("    if not isinstance(%s, term.Callable):" %
                        (varname, ))
            code.append("        if isinstance(%s, term.Var):" % (varname, ))
            code.append("           error.throw_instantiation_error()")
            code.append("        error.throw_type_error('callable', %s)" %
                        (varname, ))
        elif spec == "raw":
            code.append("    %s = query.argument_at(%s)" % (varname, i))
        elif spec == "int":
            code.append("    %s = helper.unwrap_int(%s)" % (varname, varname))
        elif spec == "atom":
            code.append("    %s = helper.unwrap_atom(%s)" % (varname, varname))
        elif spec == "arithmetic":
            code.append("    %s = eval_arithmetic(engine, %s)" %
                        (varname, varname))
        elif spec == "list":
            code.append("    %s = helper.unwrap_list(%s)" % (varname, varname))
        elif spec == "stream":
            code.append("    %s = helper.unwrap_stream(engine, %s)" %
                        (varname, varname))
        elif spec == "instream":
            code.append("    %s = helper.unwrap_instream(engine, %s)" %
                        (varname, varname))
        elif spec == "outstream":
            code.append("    %s = helper.unwrap_outstream(engine, %s)" %
                        (varname, varname))
        else:
            assert 0, "not implemented " + spec
    if needs_module:
        subargs.insert(2, "module")
        assert orig_funcargs[2] == "module"
    if needs_rule:
        subargs.insert(2, "rule")
        assert orig_funcargs[2] == "rule"
    if handles_continuation:
        subargs.append("scont")
        subargs.append("fcont")
        assert orig_funcargs[subargs.index("scont")] == "scont"
        assert orig_funcargs[subargs.index("fcont")] == "fcont"
    call = "    result = %s(%s)" % (func.func_name, ", ".join(subargs))
    code.append(call)
    if not handles_continuation:
        code.append("    return scont, fcont, heap")
    else:
        code.append("    return result")

    used_globals = ["helper", "error", "term", "eval_arithmetic"]
    miniglobals = {key: globals()[key] for key in used_globals}
    miniglobals[func.func_name] = func
    exec py.code.Source("\n".join(code)).compile() in miniglobals
    for name in expose_as:
        signature = Signature.getsignature(name, numargs)
        b = Builtin(miniglobals[funcname], funcname, numargs, signature)
        signature.set_extra("builtin", b)
    return func
コード例 #36
0
import py
from prolog.builtin.register import expose_builtin
from prolog.interpreter.term import Atom, Callable, Var, Term, Number
from prolog.interpreter import error
from prolog.builtin.sourcehelper import get_source
from prolog.interpreter import continuation
from prolog.interpreter.helper import is_term, unwrap_predicate_indicator
from prolog.interpreter.signature import Signature

meta_args = list("0123456789:?+-")
libsig = Signature.getsignature("library", 1)
andsig = Signature.getsignature(",", 2)


@expose_builtin("module", unwrap_spec=["atom", "list"])
def impl_module(engine, heap, name, exports):
    engine.modulewrapper.add_module(name, exports)


def handle_use_module_with_library(engine, heap, module, path, imports=None):
    import os
    import os.path
    from prolog.builtin.sourcehelper import get_filehandle
    newpath = None

    if path.signature().eq(libsig):
        arg = path.argument_at(0)
        if isinstance(arg, Var) or not isinstance(
                arg, Atom):  # XXX throw different errors
            error.throw_instantiation_error()
        modulename = arg.name()
コード例 #37
0
ファイル: function.py プロジェクト: sebdumancic/pyrolog
from prolog.interpreter.term import Callable, Atom, Var
from prolog.interpreter.memo import EnumerationMemo
from prolog.interpreter.signature import Signature
from rpython.rlib import jit, objectmodel, unroll
from prolog.interpreter.helper import is_callable
# XXX needs tests

cutsig = Signature.getsignature("!", 0)
prefixsig = Signature.getsignature(":", 2)


class Rule(object):
    _immutable_ = True
    _immutable_fields_ = ["headargs[*]", "groundargs[*]"]
    _attrs_ = [
        'next', 'head', 'headargs', 'groundargs', 'contains_cut', 'body',
        'env_size_shared', 'env_size_body', 'env_size_head', 'signature',
        'module', 'file_name', 'line_range', 'source'
    ]
    unrolling_attrs = unroll.unrolling_iterable(_attrs_)

    def __init__(self, head, body, module, next=None):
        from prolog.interpreter import helper
        head = head.dereference(None)
        assert isinstance(head, Callable)
        memo = EnumerationMemo()
        self.head = h = head.enumerate_vars(memo)
        memo.in_head = False
        if h.argument_count() > 0:
            self.headargs = h.arguments()
            # an argument is ground if enumeration left it unchanged, because
コード例 #38
0
ファイル: control.py プロジェクト: cosmoharrigan/pyrolog
from prolog.interpreter import helper, term, error, continuation
from prolog.builtin.register import expose_builtin
from prolog.interpreter.signature import Signature

ifsig = Signature.getsignature("->", 2)
cutsig = Signature.getsignature("!", 0)
FAILATOM = term.Callable.build("fail")
TRUEATOM = term.Callable.build("true")

# ___________________________________________________________________
# control predicates

@expose_builtin("fail", unwrap_spec=[])
def impl_fail(engine, heap):
    raise error.UnificationFailed()

@expose_builtin("true", unwrap_spec=[])
def impl_true(engine, heap):
    return

@expose_builtin("repeat", unwrap_spec=[], handles_continuation=True)
def impl_repeat(engine, heap, scont, fcont):
    return scont, RepeatContinuation(engine, scont, fcont, heap), heap.branch()

class RepeatContinuation(continuation.FailureContinuation):
    def fail(self, heap):
        heap = heap.revert_upto(self.undoheap)
        return self.nextcont, self, heap

@expose_builtin("!", unwrap_spec=[], handles_continuation=True)
def impl_cut(engine, heap, scont, fcont):
コード例 #39
0
ファイル: reasoning.py プロジェクト: hellozhaojian/CORGI
def getDependencyTupleTraverse(analyzedStatement, namedEntities, prolog):
    def removeRepeats(lst):
        seen = set()
        seen_add = seen.add
        noRepeats = [x for x in lst if not (x in seen or seen_add(x))]
        return noRepeats

    predicate = ''
    arguments = []
    statementObj = list(analyzedStatement.sents)[0]
    rootToken = statementObj.root
    if rootToken.pos_ == 'VERB':
        predicate = rootToken.lemma_.lower()
    hasVerb = 0
    iterateArgs = ['', '', '', '', '', '']
    for token in analyzedStatement:
        if token.pos_ == 'VERB':
            hasVerb = 1
        if predicate == '':
            if token.pos_ == 'VERB' and token.dep_ != 'aux':
                predicate = token.lemma_.lower()
        if 'obj' in token.dep_:
            if iterateArgs[1] == '':
                iterateArgs[1] = token.text.lower()
            else:
                if token.dep_ == 'dobj':
                    iterateArgs[1] = token.text.lower()
        elif 'subj' in token.dep_:
            iterateArgs[0] = token.text.lower()
        elif 'comp' in token.dep_:
            iterateArgs[2] = token.text.lower()
        elif 'mod' in token.dep_:
            iterateArgs[3] = token.text.lower()
        elif 'conj' in token.dep_:
            iterateArgs[4] = token.text.lower()
        elif 'oprd' in token.dep_:
            iterateArgs[5] = token.text.lower()

    if predicate == '':
        for token in analyzedStatement:
            if hasVerb and token.pos_ == 'VERB':
                predicate = token.lemma_.lower()
                break
            elif (not hasVerb) and token.dep_ == 'ROOT':
                predicate = token.text.lower()
                break

    for child in rootToken.children:
        if child.pos_ != 'PART' and child.pos_ not in ['PUNC', 'SPACE']:
            ctext = child.text.lower()
            arguments.append(ctext)
        else:
            pass

    spacyArguments = []
    for chunk in analyzedStatement.noun_chunks:
        np = chunk.text.lower().replace(' ', '_')
        if chunk.root.head.text.lower() != predicate and \
           chunk.root.head.pos_ != 'VERB'            and \
           chunk.root.head.text.lower() not in np:
            np = chunk.root.head.text.lower().replace(' ', '_') + '_' + np

        spacyArguments.append(np)

    for arg in iterateArgs:
        if arg != predicate and not any(
            [arg in sargs for sargs in spacyArguments]):
            spacyArguments.append(arg)
    spacyArguments = removeRepeats(spacyArguments)
    for ne in namedEntities:
        used = 0
        for ind, arg in enumerate(spacyArguments):
            if arg in ne[0] or ne[0] in arg:
                used = 1
                break
        if used == 0 and ne[0] not in spacyArguments:
            spacyArguments.append(ne[0].replace(' ', '_'))
    spacyArguments = removeRepeats(spacyArguments)

    if VERBOSE:
        print('spacyArguments: {0}'.format(spacyArguments))
    logging.debug('spacyArguments: {0}'.format(spacyArguments))
    sig = Signature.getsignature(str(predicate), len(spacyArguments))
    isBuiltin = prolog.get_builtin(sig)
    if isBuiltin or str(predicate) == 'close' or str(predicate) == 'open':
        predicate = predicate + '_new'
    statementTupleSpacy = '{0}({1})'.format(predicate,
                                            ','.join(spacyArguments))
    if VERBOSE:
        print 'statementTupleSpacy:', statementTupleSpacy

    statementTuple = '{0}({1})'.format(predicate, ','.join(arguments))
    if predicate == '':
        logging.error('predicate name cannot be empty, debugging needed')
    assert predicate, 'predicate name cannot be empty, debugging needed'
    return [statementTupleSpacy, predicate, spacyArguments]
コード例 #40
0
import py
from prolog.interpreter import helper, term, error
from prolog.interpreter.signature import Signature
from prolog.builtin.register import expose_builtin

# ___________________________________________________________________
# database

prefixsig = Signature.getsignature(":", 2)
implsig = Signature.getsignature(":-", 2)


def unpack_modname_and_predicate(rule):
    if helper.is_numeric(rule.argument_at(0)):
        error.throw_domain_error("atom", rule.argument_at(0))
        assert 0, "unreachable"
    mod = rule.argument_at(0)
    indicator = rule.argument_at(1)
    if not isinstance(mod, term.Atom):
        raise error.UnificationFailed()
        assert 0, "unreachable"
    return mod.name(), indicator


@expose_builtin("abolish", unwrap_spec=["callable"], needs_module=True)
def impl_abolish(engine, heap, module, predicate):
    modname = None
    if predicate.signature().eq(prefixsig):
        modname, predicate = unpack_modname_and_predicate(predicate)
    name, arity = helper.unwrap_predicate_indicator(predicate)
    if arity < 0:
コード例 #41
0
ファイル: database.py プロジェクト: cosmoharrigan/pyrolog
import py
from prolog.interpreter import helper, term, error
from prolog.interpreter.signature import Signature
from prolog.builtin.register import expose_builtin

# ___________________________________________________________________
# database

prefixsig = Signature.getsignature(":", 2)
implsig = Signature.getsignature(":-", 2)

def unpack_modname_and_predicate(rule):
    if helper.is_numeric(rule.argument_at(0)):
        error.throw_domain_error("atom", rule.argument_at(0))
        assert 0, "unreachable"
    mod = rule.argument_at(0)
    indicator = rule.argument_at(1)
    if not isinstance(mod, term.Atom):
        raise error.UnificationFailed()
        assert 0, "unreachable"
    return mod.name(), indicator

@expose_builtin("abolish", unwrap_spec=["callable"], needs_module=True)
def impl_abolish(engine, heap, module, predicate):
    modname = None
    if predicate.signature().eq(prefixsig):
        modname, predicate = unpack_modname_and_predicate(predicate)
    name, arity = helper.unwrap_predicate_indicator(predicate)
    if arity < 0:
        error.throw_domain_error("not_less_than_zero", term.Number(arity))
    signature = Signature.getsignature(name, arity)
コード例 #42
0
ファイル: modules.py プロジェクト: cosmoharrigan/pyrolog
import py
from prolog.builtin.register import expose_builtin
from prolog.interpreter.term import Atom, Callable, Var, Term, Number
from prolog.interpreter import error
from prolog.builtin.sourcehelper import get_source
from prolog.interpreter import continuation
from prolog.interpreter.helper import is_term, unwrap_predicate_indicator
from prolog.interpreter.signature import Signature

meta_args = list("0123456789:?+-")
libsig = Signature.getsignature("library", 1)
andsig = Signature.getsignature(",", 2)

@expose_builtin("module", unwrap_spec=["atom", "list"])
def impl_module(engine, heap, name, exports):
    engine.modulewrapper.add_module(name, exports)

def handle_use_module_with_library(engine, heap, module, path, imports=None):
    import os
    import os.path
    from prolog.builtin.sourcehelper import get_filehandle
    newpath = None
    if path.signature().eq(libsig):
        arg = path.argument_at(0)
        if isinstance(arg, Var) or not isinstance(arg, Atom): # XXX throw different errors
            error.throw_instantiation_error()
        modulename = arg.name()
        assert modulename is not None
        for libpath in engine.modulewrapper.libs:
            temppath = os.path.join(libpath, modulename)
            try:
コード例 #43
0
ファイル: register.py プロジェクト: cosmoharrigan/pyrolog
def make_wrapper(func, name, unwrap_spec=[], handles_continuation=False,
                   translatable=True, needs_module=False, needs_rule=False):
    numargs = len(unwrap_spec)
    if isinstance(name, list):
        expose_as = name
        name = name[0]
    else:
        expose_as = [name]
    if not name.isalnum():
        name = func.func_name
    orig_funcargs = inspect.getargs(func.func_code)[0]
    funcname = "wrap_%s_%s" % (name, numargs)
    code = ["def %s(engine, query, rule, scont, fcont, heap):" % (funcname, )]
    code.append("    module = rule.module")
    if not translatable:
        code.append("    if we_are_translated():")
        code.append("        raise error.UncatchableError('%s does not work in translated version')" % (name, ))
    subargs = ["engine", "heap"]
    assert orig_funcargs[0] == "engine"
    assert orig_funcargs[1] == "heap"
    code.append("    assert isinstance(query, term.Callable)")
    for i, spec in enumerate(unwrap_spec):
        varname = "var%s" % (i, )
        subargs.append(varname)
        if spec in ("obj", "callable", "int", "atom", "arithmetic", "instream", "outstream", "stream", "list"):
            code.append("    %s = query.argument_at(%s).dereference(heap)" %
                        (varname, i))
        if spec in ("int", "atom", "arithmetic", "list", "instream", "outstream", "stream"):
            code.append(
                "    if isinstance(%s, term.Var):" % (varname,))
            code.append(
                "        error.throw_instantiation_error()")
        if spec == "obj":
            pass
        elif spec == "callable":
            code.append(
                "    if not isinstance(%s, term.Callable):" % (varname,))
            code.append(
                "        if isinstance(%s, term.Var):" % (varname,))
            code.append(
                "           error.throw_instantiation_error()")
            code.append(
                "        error.throw_type_error('callable', %s)" % (varname,))
        elif spec == "raw":
            code.append("    %s = query.argument_at(%s)" % (varname, i))
        elif spec == "int":
            code.append("    %s = helper.unwrap_int(%s)" % (varname, varname))
        elif spec == "atom":
            code.append("    %s = helper.unwrap_atom(%s)" % (varname, varname))
        elif spec == "arithmetic":
            code.append("    %s = eval_arithmetic(engine, %s)" %
                        (varname, varname))
        elif spec == "list":
            code.append("    %s = helper.unwrap_list(%s)" % (varname, varname))
        elif spec == "stream":
            code.append("    %s = helper.unwrap_stream(engine, %s)" % (varname, varname))
        elif spec == "instream":
            code.append("    %s = helper.unwrap_instream(engine, %s)" % (varname, varname))
        elif spec == "outstream":
            code.append("    %s = helper.unwrap_outstream(engine, %s)" % (varname, varname))
        else:
            assert 0, "not implemented " + spec
    if needs_module:
        subargs.insert(2, "module")
        assert orig_funcargs[2] == "module"
    if needs_rule:
        subargs.insert(2, "rule")
        assert orig_funcargs[2] == "rule"
    if handles_continuation:
        subargs.append("scont")
        subargs.append("fcont")
        assert orig_funcargs[subargs.index("scont")] == "scont"
        assert orig_funcargs[subargs.index("fcont")] == "fcont"
    call = "    result = %s(%s)" % (func.func_name, ", ".join(subargs))
    code.append(call)
    if not handles_continuation:
        code.append("    return scont, fcont, heap")
    else:
        code.append("    return result")

    used_globals = ["helper", "error", "term", "eval_arithmetic"]
    miniglobals = {key: globals()[key] for key in used_globals}
    miniglobals[func.func_name] = func
    exec py.code.Source("\n".join(code)).compile() in miniglobals
    for name in expose_as:
        signature = Signature.getsignature(name, numargs)
        b = Builtin(miniglobals[funcname], funcname, numargs, signature)
        signature.set_extra("builtin", b)
    return func
コード例 #44
0
from prolog.builtin.register import expose_builtin
from prolog.interpreter import continuation
from prolog.interpreter.term import AttVar, Var, Callable, Atom
from prolog.interpreter.error import UnificationFailed,\
throw_representation_error, throw_instantiation_error
from prolog.interpreter.helper import wrap_list, is_term, unwrap_list
from prolog.interpreter.signature import Signature
from prolog.builtin.term_variables import term_variables

conssig = Signature.getsignature(".", 2)

@expose_builtin("attvar", unwrap_spec=["obj"])
def impl_attvar(engine, heap, obj):
    if not isinstance(obj, AttVar):
        raise UnificationFailed()
    if obj.is_empty():
        raise UnificationFailed()
        
@expose_builtin("put_attr", unwrap_spec=["obj", "atom", "obj"])
def impl_put_attr(engine, heap, var, attr, value):
    if isinstance(var, AttVar):
        old_value, _ = var.get_attribute(attr)
        var.add_attribute(attr, value)
        _, index = var.get_attribute(attr)
        heap.trail_new_attr(var, index, old_value)
    elif isinstance(var, Var):
        attvar = heap.new_attvar()
        attvar.add_attribute(attr, value)
        var.unify(attvar, heap)
    else:
        throw_representation_error("put_attr/3",