Online Prolog Compiler

Run Prolog programs online with SWI-Prolog compiled to WebAssembly: facts, rules, recursion, findall and format, with errors and warnings shown.

SWI-Prolog 10 (swipl-wasm) · Runs in your browser, so your code never reaches our servers.
main.plProlog
Output

            
        
Ctrl/⌘ + Enter to run

How to use the online Prolog compiler

  1. Write your facts and rules in the editor, or start from the example with Reset example.
  2. Say what to run with an :- initialization(main). directive, where main is a predicate that calls the goals you want to try and prints the results.
  3. Press Run or use Ctrl + Enter (⌘ + Enter on a Mac). The program is loaded as the file main.pl, and its directives run as it loads.
  4. Check the Output panel for printed text, errors and warnings. Choose a time limit of 5, 15 or 60 seconds, and use Stop if a recursion never ends.

The SWI-Prolog runtime is about 4 MB and is cached by your browser after the first visit. Keep your program with Copy or the main.pl download, resize the text with A− and A+, switch the pane layout with the layout button, and use Full screen (Ctrl/⌘ + Shift + F, Esc to exit) for longer programs.

Everything runs in your browser. The program is never sent to a server, and the editor saves your last version only in your browser's local storage.

What's supported

The page uses SWI-Prolog 10 compiled to WebAssembly (swipl-wasm). It is the actual SWI-Prolog system, not a simplified interpreter.

  • Consulting a file: your code is loaded exactly as consult('main.pl') would load it, so clauses, operators and directives all work.
  • Output predicates: format/2, write/1, writeln/1, print/1 and nl/0 all print to the output panel.
  • Lists and all-solutions predicates: member/2, append/3, length/2, msort/2, findall/3, bagof/3, setof/3, forall/2.
  • Arithmetic with is/2 and the comparison operators, on integers and floats. The example's 20! is computed exactly.
  • Diagnostics as SWI-Prolog prints them, for example singleton-variable warnings and errors such as ERROR: ... Arithmetic: `foo/0' is not a function.

What's different from a desktop Prolog:

  • There is no interactive ?- query prompt, so you cannot type queries and press ; for more answers. Put the queries in main and print the answers, or collect all of them with findall/3 or forall/2.
  • No standard input. read/1 has nothing to read from, so write your test data as facts.

Prolog basics in one program

% Facts
likes(mary, wine).
likes(john, wine).
likes(john, mary).

% A rule: X and Y are friends if both like the same thing
friends(X, Y) :- likes(X, Z), likes(Y, Z), X \== Y.

% Recursion over a list, with an accumulator
sum_list_acc([], Acc, Acc).
sum_list_acc([H|T], Acc0, Sum) :- Acc1 is Acc0 + H, sum_list_acc(T, Acc1, Sum).

% The cut (!) commits to the first matching clause
max(X, Y, X) :- X >= Y, !.
max(_, Y, Y).

main :-
    findall(X-Y, friends(X, Y), Pairs), writeln(Pairs),
    sum_list_acc([1,2,3,4], 0, S), format("sum = ~w~n", [S]),
    max(3, 7, M), format("max = ~w~n", [M]).

:- initialization(main).

Running it prints [mary-john,john-mary], sum = 10 and max = 7.

Common pitfalls

  • = is unification, not assignment or arithmetic. X = 1 + 2 binds X to the term 1+2. Use X is 1 + 2 to evaluate it, and =:= to compare two numbers.
  • Variables start with an uppercase letter or _. name is an atom and Name is a variable, so a lowercase typo silently changes the meaning of a clause.
  • Singleton warnings mean a variable appears only once in a clause, which is usually a typo. Rename it to _ or _Name if it is intentionally unused.
  • Use the cut with care. The max/3 above is fine for max(3, 7, M), but the second clause depends on the cut, so max(5, 3, 3) wrongly succeeds. Writing max(X, Y, Y) :- X < Y. as the second clause makes it safe. A misplaced cut can also hide solutions that findall would otherwise return.
  • Left recursion loops. A rule like ancestor(X, Y) :- ancestor(X, Z), parent(Z, Y). recurses forever. Put the parent goal first.
Tip: If main fails instead of succeeding, SWI-Prolog prints a warning that the initialization goal failed. Add writeln/1 calls between the goals to see how far it gets.

Frequently asked questions

How do I run a query?

Write it inside a predicate such as main and add :- initialization(main). at the end of the file. You can also put a goal directly in a directive, for example :- X is 2^10, writeln(X).

Is this standard Prolog?

It is SWI-Prolog, which follows the ISO standard and adds many extensions. Double-quoted text is a string in SWI-Prolog, which matters if you are used to it meaning a list of character codes.

Can I get every answer to a query?

Yes. Use findall/3 to collect them into a list, or forall/2 to print each one, as the example program does.

Are other logic or functional languages available?

Try the online Scheme interpreter or the online Clojure compiler, or see all online compilers.

Copied to clipboard