summaryrefslogtreecommitdiff
path: root/prolog
diff options
context:
space:
mode:
authorTimotej Lazar <timotej.lazar@araneo.org>2014-03-28 14:59:53 +0100
committerAleš Smodiš <aless@guru.si>2015-08-11 14:25:59 +0200
commitc580b4d7f4a91432f967d0ada459cd925f604caf (patch)
treed2e63ed4d4b762239637260aba4baf63524720fa /prolog
parentfc98c0412558d9ccbe65e45f32a55a0edf8683ea (diff)
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
Diffstat (limited to 'prolog')
-rwxr-xr-xprolog/engine.py26
-rw-r--r--prolog/sandbox.pl1
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(_)).