From c580b4d7f4a91432f967d0ada459cd925f604caf Mon Sep 17 00:00:00 2001 From: Timotej Lazar Date: Fri, 28 Mar 2014 14:59:53 +0100 Subject: Improve testing procedure - only run queries with correct code once - use msort/2 to implement quicksort/3, used for some tests - correctly split programs in the presence of =.. operator --- prolog/engine.py | 26 ++++++++++++++++++++++---- prolog/sandbox.pl | 1 + 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/prolog/engine.py b/prolog/engine.py index 9e7340f..7f91a30 100755 --- a/prolog/engine.py +++ b/prolog/engine.py @@ -3,6 +3,7 @@ import re from prolog.core import * +from prolog.util import * class Atom(object): __slots__ = 'ref' @@ -41,7 +42,7 @@ class Term(object): def __str__(self): ptr = c_char_p() - if PL_get_chars(self.ref, byref(ptr), CVT_ALL|CVT_WRITE|BUF_RING): + if PL_get_chars(self.ref, byref(ptr), CVT_WRITE|BUF_RING): return str(ptr.value, encoding=encoding) class Termv(object): @@ -111,11 +112,16 @@ class PrologEngine(object): return out == 1 def load(self, program, module=None): + tokens = tokenize(program) refs = [] try: - for rule in re.split('\.(?:\s+|\Z)', program): - if rule == '': + start = 0 + for idx in range(len(tokens)): + if tokens[idx] != ('PERIOD', '.') or idx - start <= 1: continue + rule = stringify(tokens[start:idx]) + start = idx + 1 + if module != None: rule = module + ':(' + rule + ')' args = Termv([Term(rule), Term('Ref')]) @@ -150,10 +156,12 @@ class PrologEngine(object): # parse term if not PL_call_predicate(None, self.err_flags, self.p['read_term_from_atom'], Termv([Term(Atom(q)), goal, options]).ref): + sys.stderr.write('WARNING: Could not read term from {}\n'.format(q)) return None # check if goal is safe with currently loaded rules if not PL_call_predicate(None, self.err_flags, self.p['safe_goal'], Termv([goal]).ref): + sys.stderr.write('WARNING: Unsafe goal: {}\n'.format(q)) return None solutions = [] @@ -162,7 +170,16 @@ class PrologEngine(object): Termv([Term(0.01), goal]).ref) while len(solutions) < 10: if PL_next_solution(qid): - solutions += [str(var_list)] + # get variable values in this solution as strings + variables = {} + head, tail = Term(), Term() + while PL_get_list(var_list.ref, head.ref, tail.ref): + name, value = Term(), Term() + PL_get_arg(1, head.ref, name.ref) + PL_get_arg(2, head.ref, value.ref) + variables[str(name)] = str(value) + var_list = tail + solutions += [variables] else: ex = PL_exception(qid) if ex != None: @@ -176,6 +193,7 @@ class PrologEngine(object): else: sys.stderr.write('Unknown error\n') break + PL_close_query(qid) PL_discard_foreign_frame(fid) diff --git a/prolog/sandbox.pl b/prolog/sandbox.pl index 2ba5af0..a4f7426 100644 --- a/prolog/sandbox.pl +++ b/prolog/sandbox.pl @@ -208,6 +208,7 @@ safe_primitive(var(_)). safe_primitive(nonvar(_)). safe_primitive(integer(_)). safe_primitive(float(_)). +safe_primitive(number(_)). safe_primitive(atom(_)). safe_primitive(compound(_)). safe_primitive(ground(_)). -- cgit v1.2.1