Use the terminal IDE¶
2PPy comes with 2ppy TUI, a terminal IDE (a text user interface, TUI) for Prolog, built with Textual. It runs in any terminal, also over SSH, and mirrors 2P-Kt's Swing IDE: the same pages, controls and panels. You can run it in your own Python environment, or with Docker, without installing anything else. How the terminal IDE works explains what happens behind its screen.
Install and start it locally¶
The terminal IDE is part of the 2ppy package: it needs Python 3.10 or later, and nothing else
(no Java installation: the package bundles a Java runtime). Either install it as a command of its
own, in an environment of its own:
uv tool install 2ppy # or: pipx install 2ppy
2ppy-tui
or run it without installing it:
uvx --from 2ppy 2ppy-tui
or install 2ppy in the environment of your project, then start the IDE from there:
pip install 2ppy # or: uv add 2ppy
2ppy-tui # or: python -m tuprolog.tui
The IDE starts with an empty scratch page. Starting takes a few seconds: the first time
tuprolog is imported, the Java virtual machine starts in the background. Quit with ctrl+q.
Any modern terminal works (e.g. Windows Terminal, iTerm2, GNOME Terminal, the terminal of VS Code); the older macOS Terminal shows fewer colors. The mouse works too: click tabs and buttons, and scroll the panels.
Start it with Docker¶
Each release of 2PPy also comes as a Docker image, for amd64 and arm64 machines, on GitHub
Packages: ghcr.io/tuprolog/2ppy, tagged with the version of 2PPy (:<version>) and :latest.
It holds Python and 2PPy only, and starts the terminal IDE:
docker run -it --rm ghcr.io/tuprolog/2ppy
-it gives the IDE a terminal (without it, it cannot start), and --rm deletes the container on
exit. Arguments after the image name are those of 2ppy-tui (see the next section), and so are
environment variables.
The IDE runs in the /work directory of the container: to open and save files of your machine,
mount a directory there. For example, to edit family.pl from the current directory:
docker run -it --rm -v "$PWD:/work" ghcr.io/tuprolog/2ppy family.pl
The IDE runs as a user with id 1000. On Linux, if your user has another id, run the container with yours, so that it can save files in the mounted directory:
docker run -it --rm -v "$PWD:/work" --user "$(id -u):$(id -g)" ghcr.io/tuprolog/2ppy family.pl
The image can also run Python, with 2PPy installed:
docker run -it --rm --entrypoint python ghcr.io/tuprolog/2ppy
Configure it from the command line¶
2ppy-tui --help lists every option. Files given as arguments open a page each (their text is the
static knowledge base of the page's solver; missing files are created on save); the other options
set the initial pages, and how every solver is built:
| Option | Effect |
|---|---|
FILE ... |
open each file in a page |
-t, --theory TEXT |
open a scratch page with this theory |
-q, --query QUERY |
the query of the initial pages |
-s, --solve [one\|ten\|hundred\|all] |
solve the query at startup, asking for 1 (default), 10, 100 or all solutions |
--stdin TEXT, --stdin-file FILE |
the standard input of the initial pages |
--dialect prolog\|problog |
the logic language: ProbLog solutions show their probability |
-d, --dynamic-kb FILE |
clauses for the dynamic knowledge base of every solver (also after a reset; repeatable) |
-l, --library SPEC |
load a library: io, oop (Python objects), oop-jvm (JVM objects), or MODULE:NAME / FILE.py:NAME naming a library, or a function returning one (repeatable) |
--no-default-libraries |
load only the --library ones (by default, io and oop) |
--oop-allow-all-imports, --oop-allow-private |
let the oop library import any module, or reach private attributes |
--no-builtins |
solvers without the standard library |
--unificator SPEC |
MODULE:NAME / FILE.py:NAME of a unificator, or of a function returning one |
-f, --flag NAME=VALUE |
set a flag of every solver, e.g. unknown=fail (repeatable) |
--timeout SECONDS |
the default timeout of resolutions (default: 5) |
--scheduling concurrent\|single |
whether resolutions of different pages run concurrently, or starting one stops the others |
For example:
2ppy-tui family.pl -q "ancestor(abe, X)" --solve ten
2ppy-tui --dialect problog -t "0.3::rain. wet :- rain." -q wet --solve
2ppy-tui --dynamic-kb facts.pl --library mylibs:geometry --flag unknown=fail
With environment variables¶
Each option can also be set by an environment variable: TWOPPY_ followed by its long name in
upper case, with _ for - (e.g. TWOPPY_QUERY for --query, TWOPPY_DYNAMIC_KB for
--dynamic-kb). Its value is:
- that of the option, for options with one (e.g.
TWOPPY_SOLVE=ten); true(or1,yes,on), for options without one (e.g.TWOPPY_NO_BUILTINS=true);- space-separated values, quoted as in a shell, for repeatable ones (e.g.
TWOPPY_FLAG="unknown=fail occurs_check=true").
TWOPPY_FILES lists the files to open, and empty variables are ignored. Command-line arguments
come after the variables: they override single values (e.g. a query), and add to repeated ones
(e.g. flags, files). This is handy with Docker, e.g. to start with a theory, and solve a query:
docker run -it --rm -e TWOPPY_THEORY="p(1). p(2)." -e TWOPPY_QUERY="p(X)" -e TWOPPY_SOLVE=all \
ghcr.io/tuprolog/2ppy
Edit and query¶
The IDE shows pages, as tabs. Each page has:
- a theory, at the top: the clauses queries are solved against;
- a query (after
?-), with the buttons solving it (Solve,Solve 10,Solve 100,Solve all), stopping a resolution (Stop), and resetting the solver (Reset, discarding the clauses queries added), and the timeout of the page's resolutions (e.g.500ms,2s 500ms,1m 30s, ornone; Enter, or leaving the field, applies it); - panels, as tabs at the bottom (a
●marks those with news):
| Panel | Shows |
|---|---|
| Solutions | the concluded resolutions, then the current one (Clear solutions forgets the former) |
| Stdin | the standard input queries read from (editable) |
| Stdout, Stderr | the standard output and error queries write to |
| Warnings | the solver's warnings (e.g. calls to unknown predicates) |
| Diagnostics | the problems found in the theory (e.g. syntax errors): Enter on one moves the editor's cursor there |
| Operators | the operators the solver knows: priority, specifier, name (Add operator declares one at the end of the theory, as :- op(700, xfx, ===).) |
| Flags | the solver's flags: Enter on one changes its value (from the next resolution on) |
| Libraries | the solver's libraries, with their predicates, operators and functions (Enter on one shows its documentation) |
| Static KB, Dynamic KB | the solver's static and dynamic knowledge bases (e.g. the clauses assertz added) |
Below the flags and the libraries, a line previews the documentation of the highlighted one;
F1 (or the Documentation button) shows it in full.
The theory, the query and the knowledge bases are colored by syntax (variables, functors, numbers, strings, comments, ...), as the operators the solver knows read them.
Solving asks for 1, 10, 100 or all solutions: if more may follow, the buttons become Next,
Next 10, Next 100 and Next all. Pressing Enter in the query solves it, as Solve (or
Next) does.
Work with files¶
Scratch pages have their own text, lost on exit: the IDE starts with one. Other pages edit files:
create one with ctrl+n, open one with ctrl+o, save it with ctrl+s (or elsewhere, with
ctrl+e), and reload it from disk with ctrl+r. Paths are relative to the directory the IDE was
started in (/work, with Docker). A * after a page's title marks unsaved changes: closing the
page (ctrl+w), reloading it, or quitting (ctrl+q) asks what to do with them.
Keys¶
| Key | Command |
|---|---|
F5, F6, F7 |
solve (or ask for the next) 1, 10, 100 solutions |
F8 |
stop the resolution |
F9 |
reset the solver |
F1 |
the documentation of the highlighted flag, library, or library symbol |
ctrl+t |
new scratch page |
ctrl+n |
new file |
ctrl+o |
open a file |
ctrl+s, ctrl+e |
save, save as |
ctrl+r |
reload the file |
ctrl+w |
close the page |
ctrl+q |
quit |
| arrow keys | move among controls (buttons, tabs, ...), unless the focused one uses them (editors, the query, tables) |
tab, shift+tab |
move among controls |
ctrl+p |
the command palette (e.g. to change the color theme) |