33< script type = "module " >
44const statusEl = document.getElementById('status');
55const resultEl = document.getElementById('result');
6+ const inputFormEl = document.getElementById('inputForm');
7+
8+ // From http://demos.rlaanemets.com/swi-prolog-wasm/example/
69
710let bindings = null;
811let stdin = '';
@@ -32,6 +35,17 @@ const query = (bindings, input) => {
3235 / / This will execute one iteration of toplevel .
3336 call ( bindings , 'break' ) ; / / see call . js
3437}
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+ }
3549
3650// Helper to print stdout from SWI.
3751const print = (line) => {
@@ -51,8 +65,13 @@ const createBindings = (module) => {
5165 return {
5266 PL_initialise: module . cwrap ( 'PL_initialise' , 'number' , [ 'number' , 'number' ] ) ,
5367 PL_new_term_ref: module . cwrap ( 'PL_new_term_ref' , 'number' , [ ] ) ,
68+ PL_new_term_refs: module . cwrap ( 'PL_new_term_refs' , 'number' , [ 'number' ] ) ,
5469 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' ] ) ,
5675 } ;
5776} ;
5877
@@ -66,6 +85,19 @@ const call = (bindings, query) => {
6685 return ! ! bindings . PL_call ( ref , 0 ) ;
6786} ;
6887
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+
69101// This will set up the arguments necessary for the PL_initialise
70102// function and will call it.
71103// See http://www.swi-prolog.org/pldoc/doc_for?object=c(%27PL_initialise%27)
@@ -132,35 +164,26 @@ const theme = window.matchMedia &&
132164const value = `
133165:- use_module(library(lists)).
134166
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).
164187`.trim();
165188
166189require(["vs/editor/editor.main"], function () {
@@ -216,12 +239,27 @@ document.body.appendChild(Object.assign(document.createElement('script'), {
216239 defer: true ,
217240 src: "https://cdn.jsdelivr.net/gh/SWI-Prolog/swipl-wasm@7e2e2aae7aabc74e9b7ab8a6e19a1c88be10325c/dist/swipl-web.js"
218241} ));
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+ } );
219254</ script >
220255
221256<!-- <script async defer src="https://cdn.jsdelivr.net/gh/SWI-Prolog/swipl-wasm@7e2e2aae7aabc74e9b7ab8a6e19a1c88be10325c/dist/swipl-web.js"></script>-->
222257
223258< 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 >
225263< div class = "flex-container " id = "container " style = "display: flex; min-height: 100vh; " >
226264 < div id = "input " style = "flex: 1; " > </ div >
227265 < div id = "output " style = "flex: 1; " > </ div >
0 commit comments