summaryrefslogtreecommitdiff
path: root/prolog/engine.py
diff options
context:
space:
mode:
authorTimotej Lazar <timotej.lazar@araneo.org>2015-05-07 11:56:00 +0200
committerAleš Smodiš <aless@guru.si>2015-08-11 14:26:03 +0200
commita101310e4c0b3e07d9f35ef9b28647709ae2960c (patch)
treef89b94aa28f37c3428ac4c42435893fb1360801f /prolog/engine.py
parentb6a2938043d1ad4d7587db361fcefea4d4d14ee1 (diff)
Use json-html format for Prolog replies
The only way to get residuals in CLP queries.
Diffstat (limited to 'prolog/engine.py')
-rw-r--r--prolog/engine.py33
1 files changed, 27 insertions, 6 deletions
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'.*<pre class="[^"]*">(.*)</pre>.*',
- 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']