From a101310e4c0b3e07d9f35ef9b28647709ae2960c Mon Sep 17 00:00:00 2001 From: Timotej Lazar Date: Thu, 7 May 2015 11:56:00 +0200 Subject: Use json-html format for Prolog replies The only way to get residuals in CLP queries. --- prolog/engine.py | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) (limited to 'prolog/engine.py') diff --git a/prolog/engine.py b/prolog/engine.py index 50282d4..96191ae 100644 --- a/prolog/engine.py +++ b/prolog/engine.py @@ -5,12 +5,16 @@ import http.client import json import re import urllib +import xml.etree.ElementTree + +def strip_html(html_str): + return ''.join(xml.etree.ElementTree.fromstring(html_str).itertext()) # 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=''): - opts = {'format': 'json-s', 'destroy': True, 'src_text': code} + opts = {'format': 'json-html', 'destroy': True, 'src_text': code} if query: opts['ask'] = query reply, messages = request('POST', '/pengine/create', body=json.dumps(opts)) @@ -39,7 +43,7 @@ def send(engine, event): params = urllib.parse.urlencode({ 'id': engine, 'event': event, - 'format': 'json-s'}) + 'format': 'json-html'}) reply, messages = request('GET', '/pengine/send?' + params) return reply @@ -64,7 +68,7 @@ def request(method, path, body=None): # Request next reply. params = urllib.parse.urlencode({ 'id': reply['id'], - 'format': 'json-s'}) + 'format': 'json-html'}) conn.request('GET', '/pengine/pull_response?' + params, headers=headers) else: return reply, messages @@ -73,9 +77,7 @@ def request(method, path, body=None): # Strip boilerplate from Prolog messages … ugly. def get_message(reply): - match = re.match(r'.*
(.*)
.*', - reply['data'], flags=re.DOTALL) - data = match.group(1).strip() + data = strip_html(reply['data']).strip() message = '' if reply['message'] == 'error': if 'location' in reply: @@ -100,6 +102,25 @@ def get_message(reply): message = re.sub(r'_G[0-9]*', '_', message) return reply['message'], message +# Return the value of variable [name] in the JSON object returned by Prolog. +def get_var(data, name): + for binding in data['variables']: + if name in binding['variables']: + return strip_html(binding['value']) + return None + +# Return a string describing variable bindings and residuals in the JSON object +# returned by Prolog. +def pretty_vars(data): + result = [] + for binding in data['variables']: + var_list = binding['variables'] + value = binding['value'] + result.append(' = '.join(var_list) + ' = ' + strip_html(value)) + if 'residuals' in data: + result += [strip_html(b) for b in data['residuals']] + return ',\n'.join(result) + # Basic sanity check. if __name__ == '__main__': engine = create(code='dup([],[]). dup([H|T],[H,H|TT]) :- dup(T,TT).')['id'] -- cgit v1.2.1