summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xmonkey/monkey.py14
-rw-r--r--prolog/engine.py66
-rw-r--r--server/prolog_session.py6
3 files changed, 32 insertions, 54 deletions
diff --git a/monkey/monkey.py b/monkey/monkey.py
index 02048de..0939448 100755
--- a/monkey/monkey.py
+++ b/monkey/monkey.py
@@ -10,12 +10,14 @@ from .util import damerau_levenshtein, PQueue
# Check whether all tests for problem [name] succeed.
def test(name, code):
- try:
- reply, output = prolog.engine.create(
- code=code, query='run_tests({})'.format(name))
- return reply.get('event') == 'success'
- except Exception as ex:
- return False
+ return False
+ # XXX currently broken
+ #try:
+ # reply, output = prolog.engine.create(
+ # code=code, query='run_tests({})'.format(name))
+ # return reply.get('event') == 'success'
+ #except Exception as ex:
+ # return False
# Starting from [code], find a sequence of edits that transforms it into a
# correct predicate for [name]. Append [aux_code] when testing (available facts
diff --git a/prolog/engine.py b/prolog/engine.py
index dc117f0..f0d1157 100644
--- a/prolog/engine.py
+++ b/prolog/engine.py
@@ -13,19 +13,12 @@ import urllib
def strip_html(text):
return html.unescape(re.sub(r'</?[a-z]+[^>]*>', '', text))
-# Create a new pengine, initialize it with [code] and return Prolog's reply.
-# The engine is destroyed after answering one query. If [query] is given, the
-# first answer is returned and the engine destroyed.
-def create(code='', query='', timeout=10):
- opts = {'format': 'json-html', 'destroy': True, 'src_text': code}
- if query:
- opts['ask'] = query
+# Create a new pengine and initialize it with [code]. Return engine ID and a
+# list of messages from Prolog.
+def create(code='', timeout=10):
+ opts = {'format': 'json-html', 'destroy': False, 'src_text': code}
reply, output = request('POST', '/pengine/create', body=json.dumps(opts), timeout=timeout)
-
- # If query was given, the actual reply is nested in create/destroy objects.
- if query:
- reply = reply['answer']['data']
- return reply, output
+ return reply.get('id'), output
def ask(engine, query, timeout=10):
return send(engine, 'ask(({}),[])'.format(query), timeout=timeout)
@@ -117,9 +110,10 @@ def pretty_vars(data):
result += [strip_html(b) for b in data['residuals']]
return ',\n'.join(result) if result else 'true'
-# Get all solutions to [query] given background knowledge [code] that are found
-# within [timeout] seconds.
-def run(code, query, timeout):
+# Run [query] in the pengine with id [engine] and return the list of answers
+# found within [timeout] seconds. If a timeout occurs before the query is done,
+# 'timed out' is appended as the last answer.
+def ask_all(engine, query, timeout):
# Returns a tuple ((bindings, constraints), error, more?) for one answer.
def process_answer(reply):
# When an engine is destroyed, a nested data object has the actual
@@ -146,52 +140,34 @@ def run(code, query, timeout):
return None, error, False
start = time.monotonic()
- result, messages = [], []
- engine = None
+ answers, messages = [], []
try:
- # Create a new pengine.
- reply, output = create(code=code, timeout=timeout)
- messages += output
- if reply.get('event') != 'create':
- raise Exception('System error: creating pengine')
- engine = reply['id']
- if 'error' in map(itemgetter(0), messages):
- return None, messages
-
# Run the query.
- real_timeout = timeout - (time.monotonic()-start)
- if real_timeout <= 0:
- raise socket.timeout()
- reply, output = ask(engine, query, real_timeout)
+ reply, output = ask(engine, query, timeout)
messages += output
if 'error' in map(itemgetter(0), output):
- return None, messages
-
- bindings, error, more = process_answer(reply)
- if bindings:
- result.append(bindings)
+ return answers, messages
+ answer, error, more = process_answer(reply)
+ if answer:
+ answers.append(answer)
if error:
messages.append(error)
- # Continue while there are more potential answers.
+ # Continue while there are more potential answers and time remaining.
while more:
real_timeout = timeout - (time.monotonic()-start)
if real_timeout <= 0:
raise socket.timeout()
reply, output = next(engine, timeout=real_timeout)
messages += output
- bindings, error, more = process_answer(reply)
- if bindings:
- result.append(bindings)
+ answer, error, more = process_answer(reply)
+ if answer:
+ answers.append(answer)
if error:
messages.append(error)
except socket.timeout as ex:
- result.append('timed out')
- finally:
- if engine:
- destroy(engine)
-
- return result, messages
+ answers.append('timed out')
+ return answers, messages
# Basic sanity check.
diff --git a/server/prolog_session.py b/server/prolog_session.py
index 768f820..ee8dba3 100644
--- a/server/prolog_session.py
+++ b/server/prolog_session.py
@@ -47,10 +47,10 @@ class PrologSession(object):
if self._engine_id is not None:
prolog.engine.stop(self._engine_id)
self._engine_id = None
- reply, output = prolog.engine.create(code=code)
- if reply.get('event') != 'create':
+ engine_id, output = prolog.engine.create(code=code)
+ if not engine_id:
raise Exception('System error: could not create a prolog engine')
- self._engine_id = reply['id']
+ self._engine_id = engine_id
messages = [text for text in map(operator.itemgetter(1), output)]
status = 'error' if 'error' in map(operator.itemgetter(0), output) else 'ok'
return messages, status, False