-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathswipl_kernel.py
107 lines (92 loc) · 3.34 KB
/
swipl_kernel.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import os
import os.path as op
import tempfile
import IPython
import jupyter_client
from IPython.utils.process import getoutput
from backports import tempfile
def exec_swipl(code):
temp_path, output_path, code_path = setup_env()
preCode1 = 'doa([]).\n\n'
preCode2 = 'doa( [G|_] ) :- write(\' \\n----------------------------------------- \\n Call of: \\t \'), write(G), call(G), write(\' \\n TRUE with:\\t \'), write(G), fail.\n\n'
preCode3 = 'doa( [G|R] ) :- not(G), !, write(\' \\n FALSE! \\t \'), write(G), doa(R).\n\n'
preCode4 = 'doa( [_|R] ) :- doa(R).\n\n'
emptyline = '\n'
startQuery = ':- doa(['
endQuery = ']).'
with open(temp_path, 'w') as f: #
f.write(code)
''' Parser code begins here '''
textlist = []
textlist.append(preCode1)
textlist.append(preCode2)
textlist.append(preCode3)
textlist.append(preCode4)
textlist.append(emptyline)
with open(temp_path) as f:
'''
some hacky logic to enable students to simply add queries
after defining their ruleset.
'''
for line in f:
textlist.append(line)
if 'QUERYSTART' in line:
textlist.pop() # get rid of start marker
textlist.append(startQuery)
if 'QUERYEND' in line:
textlist.pop() # get rid of end marker
textlist.append(endQuery)
print(''.join(textlist))
with open(code_path, 'w') as rules:
rules.write(''.join(textlist))
os.system("swipl {0:s} > {1:s} 2>&1 ".format(code_path, output_path))
l = open(output_path, 'r')
lines = l.readlines()
l.close()
lines = lines[:-9]
t = open(output_path, 'w')
for line in lines:
t.write(line)
t.close()
f = open(output_path, 'r')
return f.read()
def setup_env():
dirpath = tempfile.mkdtemp()
temp_path = op.join(dirpath, 'temp.pl')
output_path = op.join(dirpath, 'out.txt')
code_path = op.join(dirpath, 'code.pl')
return temp_path, output_path, code_path
"""SWI-Prolog kernel wrapper"""
from ipykernel.kernelbase import Kernel
class SwiplKernel(Kernel):
implementation = 'SWI-Prolog'
implementation_version = '0.0'
language = 'Prolog'
language_version = '1.0'
language_info = {'name': 'swipl',
'mimetype': 'text/plain'}
banner = "SWI-Prolog Kernel"
def do_execute(self, code, silent,
store_history=True,
user_expressions=None,
allow_stdin=False):
"""This function is called when a code cell is
executed."""
if not silent:
# We run the Prolog code and get the output.
output = exec_swipl(code)
# We send back the result to the frontend.
stream_content = {'name': 'stdout',
'text': output}
self.send_response(self.iopub_socket,
'stream', stream_content)
return {'status': 'ok',
# The base class increments the execution
# count
'execution_count': self.execution_count,
'payload': [],
'user_expressions': {},
}
if __name__ == '__main__':
from ipykernel.kernelapp import IPKernelApp
IPKernelApp.launch_instance(kernel_class=SwiplKernel)