Vibe-Prolog
AGENTS.md56 starsChanged 12 months agoMITView on GitHub
These goals are what we are working towards in this project: - A complete, widely compatible Prolog implementation - Robust: It should handle all kinds of error conditions gracefully - Fast: It should run prolog programs fast - Scalable: It should be able to run large prolog programs This document provides an overview of the project structure and guidelines for development and testing. See @docs/ARCHITECTURE.md See @docs/FEATURES.md You must keep ./docs/FEATURES.md up to date when you add or change these
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 31,700 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repository3 other files it gives its agents.
- website/AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- website/CLAUDE.mdCLAUDE.md
The file
Show its rules and text
We split this AGENTS.md into the rules it gives an agent
19 rules. About 0 are common, 16 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈16
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- could be automatic: a setting could enforce it
- Distinctive: line 10
Follow PEP 8 for Python code
- Very specific: line 12
Never use import statements inside functions or methods
- Distinctive: line 14
Run all tests before pushing a PR
- Distinctive: line 15
Use type hints where helpful
- Distinctive: line 16
Add docstrings to all public methods
- Distinctive: line 17
Keep functions focused and testable
- Distinctive: line 18
Use descriptive variable names
- Very specific: line 144
When adding a new test that consistently takes longer than ~4 seconds, mark it with @pytest.mark.performance (or set pytestmark = …
- Distinctive: line 145
Document why the test is performance-marked in its docstring when the reason is not obvious.
- Distinctive: line 176
Start with the simplest possible query
- Very specific: line 178
Put test files in tests/ directory
- Distinctive: line 217
Before implementing support for a new library
- Distinctive: line 274
Before major releases to verify ISO compliance
- Distinctive: line 275
After parser/syntax changes to catch regressions
- Distinctive: line 276
When investigating ISO compatibility issues
- Distinctive: line 289
Write tests first (TDD approach recommended)
- Distinctive: line 290
Ensure all tests pass before committing
- Distinctive: line 291
Update this documentation when adding features
- Distinctive: line 292
Keep the codebase clean and well-organized
≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Goals
These goals are what we are working towards in this project:
- A complete, widely compatible Prolog implementation
- Robust: It should handle all kinds of error conditions gracefully
- Fast: It should run prolog programs fast
- Scalable: It should be able to run large prolog programs
Coding rules
- Follow PEP 8 for Python code
- All imports must be at the top of the file (after module docstring, before other code)
- Never use
importstatements inside functions or methods - Group imports: standard library, third-party, local (separated by blank lines)
- Run all tests before pushing a PR
- Use type hints where helpful
- Add docstrings to all public methods
- Keep functions focused and testable
- Use descriptive variable names
Prolog Interpreter - Development Guide
This document provides an overview of the project structure and guidelines for development and testing.
Project Structure
See @docs/ARCHITECTURE.md
Features
See @docs/FEATURES.md
You must keep ./docs/FEATURES.md up to date when you add or change these
Documentation
All new markdown documentation should go in @docs/
Standard documentation files:
@docs/ARCHITECTURE.md- System architecture and design@docs/FEATURES.md- ISO Prolog conformance matrix and feature checklist- Any additional documentation, guides, or specs should be added as new files within the
@docs/directory.
Error Handling
Handle Prolog errors like this:
except PrologThrow:
# Re-raise Prolog errors
raise
except Exception: # Or use a more specific Exception if possible
# Unexpected errors - convert to evaluation error
raise PrologThrow(PrologError.evaluation_error("error", f"{op}/2"))Testing Guidelines
Where to Put Tests
All test files must go in the tests/ directory.
- Unit tests:
test_<module>.py- Tests for specific modules - Integration tests:
test_<feature>.py- Tests for features spanning multiple modules - Fixtures:
*.plfiles - Prolog code used by tests
Test File Naming
- Python test files:
test_*.py - Prolog fixtures:
test_*.plor descriptive names likeminimal_mi_test.pl - Follow pytest conventions
Writing Tests
- Import the interpreter:
from vibeprolog import PrologInterpreter - Create a new interpreter for each test:
def test_something(): prolog = PrologInterpreter() # Your test code - Use pytest test classes to organize related tests:
class TestAppend: """Tests for append/3 predicate.""" def test_append_two_lists(self): prolog = PrologInterpreter() result = prolog.query_once("append([1, 2], [3, 4], X).") assert result['X'] == [1, 2, 3, 4] - Test both success and failure cases:
def test_unification_success(self): prolog = PrologInterpreter() assert prolog.has_solution("X = 5") def test_unification_failure(self): prolog = PrologInterpreter() assert not prolog.has_solution("1 = 2")
Running Tests
# Run all tests
uv run pytest
# Run all tests including performance (skipped by default). This is slow so run only when required.
uv run pytest --run-performance
# Run all slow tests (tests empirically longer than ~4 seconds). Skip unless flag is present.
uv run pytest --run-slow-tests
# Run specific test file
uv run pytest tests/test_builtins.py
# Run specific test class
uv run pytest tests/test_builtins.py::TestAppend
# Run specific test
uv run pytest tests/test_builtins.py::TestAppend::test_append_two_lists
# Run with verbose output
uv run pytest -v
# Run with output capture disabled (see print statements)
uv run pytest -sLong-running tests
- When adding a new test that consistently takes longer than ~4 seconds, mark it with
@pytest.mark.performance(or setpytestmark = pytest.mark.performancefor whole classes/files) so it only runs when--run-performanceis used. - Document why the test is performance-marked in its docstring when the reason is not obvious.
Development Workflow
This is standard ISO prolog implementation. The parser should parse standard prolog syntax.
Adding a New Built-in
- Choose a module in
vibeprolog/builtins/that fits (e.g.,arithmetic.py,list_ops.py,type_tests.py). - Implement a static handler with the signature
(args, subst, engine)and annotate return types. - Register the predicate in the module's
register(registry, engine_ref=None)usingregister_builtin. - Write tests in
tests/covering success and failure cases. - Update documentation (
CLAUDE.md/FEATURES.md) to reflect the new predicate. - Run tests:
uv run pytest tests/test_new_builtins.py -v
Syntax errors: When a built-in parses text (e.g., via
PrologParserorread_from_chars/2) and the input might be malformed, wrap the parser call intry/except (ValueError, LarkError)and create an error term withPrologError.syntax_error(str(exc), "predicate/arity")then raisePrologThrow(error_term). This ensures callers can intercept the ISO-styleerror(syntax_error(_), Context)term withcatch/3.
Debugging Tips
- Use print statements in built-ins:
def _builtin_something(self, arg, subst): print(f"Debug: arg={arg}, subst={subst}") # ... - Create minimal test cases:
- Start with the simplest possible query
- Gradually add complexity
- Put test files in
tests/directory
- Check parser output:
from vibeprolog.parser import PrologParser parser = PrologParser() result = parser.parse("your_query.") print(result)
Developer Tools
The tools/ directory contains utilities for analyzing Prolog code and identifying missing functionality.
Check Operators (tools/check_operators.py)
Analyzes which operators are used in a Prolog file and compares them against what Vibe-Prolog supports.
Usage:
uv run python tools/check_operators.py <prolog_file>Example:
uv run python tools/check_operators.py library/clpb.plWhat it does:
- Finds all operators used in the code
- Identifies operators declared in
:- op(...)directives or module exports - Categorizes operators as:
- Supported (defined in
operator_defaults.py) - Unsupported ISO operators (required by standard)
- Unsupported non-ISO operators (extensions)
- Supported (defined in
- Outputs a markdown report
When to use:
- Before implementing support for a new library
- To prioritize which operators to implement
- To understand operator dependencies
- To verify ISO compliance
Exit codes:
- 0: All ISO operators are supported
- 1: Some ISO operators are missing
Find Built-ins (tools/find_builtins.py)
Scans a directory of Prolog files to identify which predicates are called but not defined, indicating they're likely built-in predicates.
Usage:
uv run python tools/find_builtins.py <directory>Example:
uv run python tools/find_builtins.py examples/What it does:
- Parses all
.plfiles in the directory - Identifies predicates that are called but not defined
- Categorizes predicates as:
- Actual built-ins (registered in Vibe-Prolog)
- Dynamic predicates (declared
:- dynamicbut asserted at runtime) - Undefined predicates (not built-in, not dynamic, not defined - might be missing)
- Shows which files use each predicate
When to use:
- To discover what built-ins are needed for a set of examples
- To identify missing implementations
- To prioritize built-in development
- To verify completeness of built-in coverage
Note: This tool identifies predicates, not operators. Operators are syntactic and checked by check_operators.py.
ISO Conformity Testing (tools/conformity_test.py)
Tests Vibe-Prolog against the official ISO Prolog conformity test suite (355 tests).
Usage:
# Run all tests and generate report
uv run python tools/conformity_test.py
# Run specific tests
uv run python tools/conformity_test.py --tests 1-50
# Verbose output
uv run python tools/conformity_test.py --verboseWhen to use:
- Before major releases to verify ISO compliance
- After parser/syntax changes to catch regressions
- When investigating ISO compatibility issues
- To track conformity improvements over time
Output: Generates docs/CONFORMITY_TESTING.md with detailed results.
Resources
- SWI-Prolog Documentation - Reference for built-in predicates
- pytest Documentation - Testing framework
- Lark Parser - Parser generator used for Prolog syntax
Contributing
- Write tests first (TDD approach recommended)
- Ensure all tests pass before committing
- Update this documentation when adding features
- Keep the codebase clean and well-organized
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

