3
3
< script type = "module " >
4
4
const statusEl = document.getElementById('status');
5
5
const resultEl = document.getElementById('result');
6
+ const inputFormEl = document.getElementById('inputForm');
7
+
8
+ // From http://demos.rlaanemets.com/swi-prolog-wasm/example/
6
9
7
10
let bindings = null;
8
11
let stdin = '';
@@ -32,6 +35,17 @@ const query = (bindings, input) => {
32
35
/ / This will execute one iteration of toplevel .
33
36
call ( bindings , 'break' ) ; / / see call . js
34
37
}
38
+ const query2 = (bindings, name, ...args) => {
39
+ / / Show the query in the console output .
40
+ const node = document . createTextNode ( `${ name } ( ${ args . join ( ', ' ) } ) . ` + '\n ' ) ;
41
+ resultEl . appendChild ( node ) ;
42
+ setStdin ( input ) ;
43
+ / / This will execute one iteration of toplevel .
44
+ / / call ( bindings , 'break' ) ; / / see call . js
45
+ const result = callPredicate ( bindings , name , ... args ) ;
46
+ resultEl . appendChild ( document . createTextNode ( JSON . stringify ( result ) + '\n ' ) ) ;
47
+ resultEl . scrollTop = resultEl . scrollHeight ;
48
+ }
35
49
36
50
// Helper to print stdout from SWI.
37
51
const print = (line) => {
@@ -51,8 +65,13 @@ const createBindings = (module) => {
51
65
return {
52
66
PL_initialise: module . cwrap ( 'PL_initialise' , 'number' , [ 'number' , 'number' ] ) ,
53
67
PL_new_term_ref: module . cwrap ( 'PL_new_term_ref' , 'number' , [ ] ) ,
68
+ PL_new_term_refs: module . cwrap ( 'PL_new_term_refs' , 'number' , [ 'number' ] ) ,
54
69
PL_chars_to_term: module . cwrap ( 'PL_chars_to_term' , 'number' , [ 'string' , 'number' ] ) ,
55
- PL_call: module . cwrap ( 'PL_call' , 'number' , [ 'number' , 'number' ] )
70
+ PL_put_atom_chars: module . cwrap ( 'PL_put_atom_chars' , 'number' , [ 'number' , 'string' ] ) ,
71
+ PL_predicate: module . cwrap ( 'PL_predicate' , 'number' , [ 'string' , 'number' , 'string' ] ) ,
72
+ PL_call: module . cwrap ( 'PL_call' , 'number' , [ 'number' , 'number' ] ) ,
73
+ PL_open_query: module . cwrap ( 'PL_open_query' , 'number' , [ 'number' , 'number' , 'number' , 'number' ] ) ,
74
+ PL_call_predicate: module . cwrap ( 'PL_call_predicate' , 'number' , [ 'number' , 'number' , 'number' , 'number' ] ) ,
56
75
} ;
57
76
} ;
58
77
@@ -66,6 +85,19 @@ const call = (bindings, query) => {
66
85
return ! ! bindings . PL_call ( ref , 0 ) ;
67
86
} ;
68
87
88
+ const callPredicate = (bindings, name, ...args) => {
89
+ const ref = bindings . PL_new_term_refs ( args . length ) ;
90
+ args . forEach ( ( arg , index ) => {
91
+ / / PL_put_atom_chars ?
92
+ if ( ! bindings . PL_chars_to_term (arg , ref + index ) ) {
93
+ throw new Error ( 'Query has a syntax error: ' + arg ) ;
94
+ }
95
+ } )
96
+ const pred = bindings . PL_predicate ( name , args . length , 0 ) ;
97
+
98
+ return !! bindings . PL_call_predicate ( 0 , 0 , pred , ref ) ;
99
+ } ;
100
+
69
101
// This will set up the arguments necessary for the PL_initialise
70
102
// function and will call it.
71
103
// See http://www.swi-prolog.org/pldoc/doc_for?object=c(%27PL_initialise%27)
@@ -132,35 +164,26 @@ const theme = window.matchMedia &&
132
164
const value = `
133
165
:- use_module(library(lists)).
134
166
135
- %% queens(+N, -Queens) is nondet.
136
- %
137
- % @param Queens is a list of column numbers for placing the queens.
138
- % @author Richard A. O'Keefe (The Craft of Prolog)
139
-
140
- queens(N, Queens) :-
141
- length(Queens, N),
142
- board(Queens, Board, 0, N, _, _),
143
- queens(Board, 0, Queens).
144
-
145
- board([], [], N, N, _, _).
146
- board([_|Queens], [Col-Vars|Board], Col0, N, [_|VR], VC) :-
147
- Col is Col0+1,
148
- functor(Vars, f, N),
149
- constraints(N, Vars, VR, VC),
150
- board(Queens, Board, Col, N, VR, [_|VC]).
151
-
152
- constraints(0, _, _, _) :- !.
153
- constraints(N, Row, [R|Rs], [C|Cs]) :-
154
- arg(N, Row, R-C),
155
- M is N-1,
156
- constraints(M, Row, Rs, Cs).
157
-
158
- queens([], _, []).
159
- queens([C|Cs], Row0, [Col|Solution]) :-
160
- Row is Row0+1,
161
- select(Col-Vars, [C|Cs], Board),
162
- arg(Row, Vars, Row-Row),
163
- queens(Board, Row, Solution).
167
+ influences(erlang, elixir).
168
+ influences(erlang, clojure).
169
+
170
+ influences(prolog, erlang).
171
+ influences(prolog, clojure).
172
+
173
+ influences(lisp, erlang).
174
+ influences(lisp, clojure).
175
+
176
+ influences(clojure, elixir).
177
+ influences(ruby, elixir).
178
+ influences(plex, erlang).
179
+ influences(smalltalk, erlang).
180
+ influences(haskell, clojure).
181
+ influences(java, clojure).
182
+
183
+ ancestor(X, Y) :- influences(X, Y).
184
+ ancestor(X, Y) :-
185
+ influences(Parent, Y),
186
+ ancestor(X, Parent).
164
187
`.trim();
165
188
166
189
require(["vs/editor/editor.main"], function () {
@@ -216,12 +239,27 @@ document.body.appendChild(Object.assign(document.createElement('script'), {
216
239
defer: true ,
217
240
src: "https://cdn.jsdelivr.net/gh/SWI-Prolog/swipl-wasm@7e2e2aae7aabc74e9b7ab8a6e19a1c88be10325c/dist/swipl-web.js"
218
241
} ));
242
+
243
+ inputForm.addEventListener('submit', {
244
+ handleEvent ( event ) {
245
+ event . preventDefault ( ) ;
246
+ const form = event . target ;
247
+ const data = new FormData ( form ) ;
248
+ const value = data . get ( 'query' ) ;
249
+ console . log ( value , new URLSearchParams ( data ) . toString ( ) ) ;
250
+ query2 ( bindings , 'ancestor' , 'java' , 'erlang' ) ;
251
+ / / form . reset ( ) ;
252
+ }
253
+ } );
219
254
</ script >
220
255
221
256
<!-- <script async defer src="https://cdn.jsdelivr.net/gh/SWI-Prolog/swipl-wasm@7e2e2aae7aabc74e9b7ab8a6e19a1c88be10325c/dist/swipl-web.js"></script>-->
222
257
223
258
< output id = status class = "block text-xs opacity-50 " > </ output >
224
- < output id = result class = "block text-xs opacity-50 " > </ output >
259
+ < output id = result class = "block max-h-16 overflow-scroll whitespace-pre-line text-xs opacity-50 " > </ output >
260
+ < form id = inputForm class = "flex flex-col " >
261
+ < input type = text name = query value = "influences(erlang, elixir). " class = "text-black bg-white border " >
262
+ </ form >
225
263
< div class = "flex-container " id = "container " style = "display: flex; min-height: 100vh; " >
226
264
< div id = "input " style = "flex: 1; " > </ div >
227
265
< div id = "output " style = "flex: 1; " > </ div >
0 commit comments