Skip to content

Commit 9631d5f

Browse files
committed
Get prolog queries working
1 parent 429d2ef commit 9631d5f

File tree

1 file changed

+69
-31
lines changed

1 file changed

+69
-31
lines changed

apps/components_guide_web/lib/components_guide_web/templates/react_typescript/editor-prolog.html.eex

Lines changed: 69 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
<script type="module">
44
const statusEl = document.getElementById('status');
55
const resultEl = document.getElementById('result');
6+
const inputFormEl = document.getElementById('inputForm');
7+
8+
// From http://demos.rlaanemets.com/swi-prolog-wasm/example/
69

710
let bindings = null;
811
let 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.
3751
const 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 &&
132164
const 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

166189
require(["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

Comments
 (0)