From 86287e6a4fa07d03aa906965a182425320e445ce Mon Sep 17 00:00:00 2001 From: Timotej Lazar Date: Thu, 27 Aug 2015 15:52:04 +0200 Subject: Replace prolog.engine.run with ask_all Creating and destroying the pengine should be handled somewhere else. This commit also removes query functionality from prolog.engine.create. --- prolog/engine.py | 66 ++++++++++++++++++-------------------------------------- 1 file changed, 21 insertions(+), 45 deletions(-) (limited to 'prolog/engine.py') 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']*>', '', 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. -- cgit v1.2.1