diff options
-rw-r--r-- | prolog/engine.py | 40 |
1 files changed, 24 insertions, 16 deletions
diff --git a/prolog/engine.py b/prolog/engine.py index 92caa0a..2878933 100644 --- a/prolog/engine.py +++ b/prolog/engine.py @@ -66,7 +66,7 @@ class Termv(object): class PrologEngine(object): def __init__(self): - # initialize Prolog library + # Initialize the swipl library. args = ['./', '-q', '--nosignals'] if SWI_HOME_DIR is not None: args.append('--home={0}'.format(SWI_HOME_DIR)) @@ -78,7 +78,7 @@ class PrologEngine(object): raise EnvironmentError('Could not initialize Prolog environment.' 'PL_initialise returned {0}'.format(result)) - # construct some predicates + # Construct some predicates. self.p = { 'add_import_module/3': PL_predicate(b'add_import_module', 3, None), 'assertz/1': PL_predicate(b'assertz', 1, None), @@ -93,9 +93,6 @@ class PrologEngine(object): } self.err_flags = PL_Q_NODEBUG|PL_Q_CATCH_EXCEPTION - # Dictionary of correct answers; keys are (pid, query). - self.answers = {} - # Increase memory limits. self.call('set_prolog_stack/2', [Term('global'), Term('limit(2*10**9)')]) self.call('set_prolog_stack/2', [Term('local'), Term('limit(2*10**9)')]) @@ -103,18 +100,20 @@ class PrologEngine(object): # Discard messages from the swipl library. self.call('assertz/1', [Term('message_hook(_, _, _)')]) + # Dictionary of correct answers; keys are (pid, query). + self.answers = {} + def exception(self, qid): ref = PL_exception(qid) - if ref is None: + if not ref: return False try: ex = Term(ref=ref) - if ex is not None: - msg = Term() - if PL_call_predicate(None, self.err_flags, - self.p['message_to_string/2'], Termv([ex, msg]).ref): - raise Exception(str(msg)) - raise Exception('Unknown error') + msg = Term() + if PL_call_predicate(None, self.err_flags, + self.p['message_to_string/2'], Termv([ex, msg]).ref): + raise Exception(str(msg)) + raise Exception('Unknown error') finally: PL_clear_exception() return False @@ -220,9 +219,18 @@ class PrologEngine(object): correct &= (len(result) == 1 and result[0]['X'] == self.answers[(pid, query)]) except Exception as ex: correct = False - finally: - # Unload all loaded rules. - for ref in refs: - self.call('erase/1', [ref]) + + # Unload all loaded rules. + for ref in refs: + self.call('erase/1', [ref]) return correct + +# Basic sanity check. +if __name__ == '__main__': + engine = PrologEngine() + engine.consult('prolog/lib.pl') + + engine.load_solution(0, 'a(2). a(2). a(3). ') + result = engine.test(0, 0, 'a(2). ', ['a(X)', 'a(Y), Y=X']) + print('{}: {}'.format(i, result)) |