You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .agents/AGENTS.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -42,6 +42,7 @@ All Prolog code (regardless of target engine) MUST follow the universal style an
42
42
- Prefer coroutining (`freeze/2`, `when/2`) to suspend goals until variables are instantiated, preferring [`CLP(Z)`](https://github.com/mthom/scryer-prolog/blob/master/src/lib/clpz.pl)/`dif/2` over manual coroutining where specialized constraints apply.
43
43
-**Direct Reification over `if_/3` for Booleans**: Always prefer direct reified predicates (e.g. `=(X, Y, Truth)`, `memberd_t/3`, `tpartition/4`) over wrapping boolean assignments inside `if_/3` (e.g. use `=(X, Y, Truth)` instead of `if_(X = Y, Truth = true, Truth = false)`). Reserve `if_/3` strictly for selecting non-boolean values (`if_(G, Val = 'yes', Val = 'no')`) or executing conditional branches with distinct control paths.
44
44
-**Prefer `cond_t` over `if_` / `->` (DRY Principle)**: Aggressively prefer `cond_t` over `if_` and `->` when choosing between choices or values based on a test. Use `cond_t` to avoid repeating the same variable or assignment in both the true and false clauses of `if_` (Don't Repeat Yourself principle).
45
+
-**Meta-Predicate Declarations (`meta_predicate`)**: When defining module-level predicates that accept callable goals (`0`), closures (`1`..`N`), DCG non-terminals (`//` or `2`), or module-sensitive terms (`:`), always insert explicit `:- meta_predicate` declarations directly below the module header. Use exact closure arities for higher-order arguments and standard specifiers (`+`, `-`, `?`, `*`) for non-callable data arguments to prevent unwanted caller module expansion.
45
46
-**Declarative AI Workflow**: [.agents/skills/prolog-declarative-workflow/SKILL.md](.agents/skills/prolog-declarative-workflow/SKILL.md)
46
47
- Use declarative reasoning based on unification, constraints, and backtracking (never imperative thinking).
Copy file name to clipboardExpand all lines: .agents/references/prolog_guidelines.md
+23Lines changed: 23 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -108,6 +108,29 @@ Prefer higher-order predicates and closures over primitive recursive list traver
108
108
-**Higher-Order DCGs (`call//N`)**: Parameterize DCG rules with closures or non-terminals using `call//N` (e.g. `call(Goal, Arg)` inside `-->`) to avoid writing duplicate grammar traversals.
109
109
-**Lambda Expressions (`library(lambda)`)**: Use `:- use_module(library(lambda)).` and lambda abstractions (`\X^...`, `\X^Y^Goal`) for inline transformations, filtering, and mapping without creating single-use helper predicates.
When exporting or defining predicates inside a module that accept callable arguments (goals `0`, closures `1`..`N`, DCG rules `//` or `2`, dynamic goals `:`), always insert explicit `:- meta_predicate` declarations directly after the module header:
114
+
115
+
-**Module Name Expansion**: Tells the module system to resolve meta-arguments in the context of the *caller module* rather than the library module, preventing runtime `existence_error` exceptions.
116
+
-**Precise Arity Specifiers**:
117
+
-`0`: 0-argument goal (executed with `call(Goal)` or direct evaluation).
118
+
-`1`..`9`: Closures receiving $N$ additional arguments (e.g. `2` for `maplist/3`, `2` for `tfilter/3`, `3` for `foldl/4`).
119
+
-`//` or `2`: DCG non-terminal closures expanded with difference lists.
120
+
-`+`, `-`, `?`, `*`: Regular non-callable data arguments.
121
+
-**Avoid Anti-Patterns**: Never declare `meta_predicate` on pure data predicates, and never mark data arguments as `:` or `0` (which would force unintended caller-module term wrapping).
122
+
123
+
```prolog
124
+
:- module(my_higher_order, [
125
+
custom_map/3,
126
+
delimited//3
127
+
]).
128
+
129
+
:- meta_predicate
130
+
custom_map(2, +, -),
131
+
delimited(//, //, //, ?, ?).
132
+
```
133
+
111
134
### Use Term & Goal Expansion to Avoid Code Duplication
112
135
113
136
Leverage Prolog's compile-time expansion hooks (`user:term_expansion/2` and `user:goal_expansion/2`) to eliminate repetitive code structures, redundant clause boilerplate, or macro-like patterns instead of duplicating logic across multiple rules.
Copy file name to clipboardExpand all lines: .agents/skills/prolog-code-review/SKILL.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,6 +16,7 @@ Use this skill when reviewing Prolog pull requests, auditing code diffs, or eval
16
16
|**Clean Data Representation**| - Can every data element kind be distinguished solely by its **principal functor** (e.g., `leaf(L)` vs `node(L, R)`)?<br>- Are defaulty representations avoided so argument indexing works automatically?<br>- Are external defaulty/unstructured inputs converted into clean trees early? |
17
17
|**Determinism & Performance**| - Do deterministic predicates leave open choice points?<br>- Is the primary input placed in the first argument position for first-argument indexing?<br>- Is `zcompare/3` used for reified integer comparisons?<br>- Are recursive calls in tail position (TCO) with accumulators? |
18
18
|**Variable Naming & Syntax**| - Are public API parameter names domain-descriptive (`Tree`, `TokenStream`) while standard short names (`X`, `Xs`, `N`) are kept in tight local contexts?<br>- Are DCG state pairs consistently named (`L0..L` / `S0..S`)?<br>- Are neck operators `:-` free of dropped characters (`:` instead of `:-`)?<br>- Are line comments formatted with `%` rather than `#` or `//`?<br>- Are DCG rules declared with `-->` rather than `->`?<br>- Are comparison operators Prolog-standard (`=\=`, `\=`, `=<`, `>=`) rather than C/Python symbols (`!=`, `<=`, `=>`)?<br>- Do module export lists (`:- module/2`), import lists (`:- use_module/2`), and doc comments use ISO `Name//Arity` indicator notation for DCG non-terminals? |
19
+
|**Meta-Predicate Declarations**| - Do all exported and module-level predicates taking callable arguments (goals `0`, closures `1`..`N`, DCG non-terminals `//` or `2`, dynamic goals `:`) have explicit `:- meta_predicate` declarations?<br>- Are closure arity extensions accurate (e.g. `2` for `maplist/3`, `2` for `tfilter/3`, `3` for `foldl/4`)?<br>- Are non-callable data arguments marked with `+`, `-`, `?`, or `*` rather than `:` or `0` to prevent unintended caller module qualification? |
19
20
|**Engine Portability**| - Are engine-specific types (SWI dicts, SWI strings) avoided in ISO / multi-engine code?<br>- Are explicit module imports declared (e.g. `:- use_module(library(dcgs)).`, `library(si)`, `library(clpz)`)? |
20
21
|**Homoiconicity & Prolog Tooling**| - If this tool/program processes or generates Prolog source, is it itself implemented in Prolog?<br>- Does the implementation follow the **ISO core + flat shim** pattern: engine-agnostic logic in `core.pl`, engine-specific differences isolated to `scryer_shim.pl` / `swi_shim.pl` / etc.?<br>- If skill or capability metadata is declared, is it represented as `skill(Name, Caps)` Prolog facts rather than external YAML/JSON config?<br>- Is skill discovery expressed as Prolog queries (`skill(Name, Caps), member(Capability, Caps)`) rather than string-matching lookups? |
21
22
|**Safety & Security**| - Is user input sanitized before `consult/1` or `read_term/2`?<br>- Are execution timeouts enforced via `prolog-safe`? |
Copy file name to clipboardExpand all lines: .agents/skills/prolog-conventions/SKILL.md
+25-10Lines changed: 25 additions & 10 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -74,16 +74,31 @@ While the module loading directive (e.g. `:- use_module(library(clpz)).` in Scry
74
74
call(Sep, X),
75
75
separated_by(Xs, Sep).
76
76
```
77
-
9.**Explicit Library Declarations**: Always explicitly import required library modules (e.g. `:- use_module(library(reif)).`, `:- use_module(library(dcgs)).`, `:- use_module(library(charsio)).`, `:- use_module(library(lambda)).`, `:- use_module(library(clpz)).`). Do not assume SWI-style autoloading when targeting ISO or embedded engines.
78
-
10.**Control Structures & CLP(Z) Constraints**: Use standard ISO control structures `(,)/2`, `(;)/2`. Prefer CLP(Z) constraints (`#=`, `#>`, `all_distinct/1`) and reified arithmetic (`zcompare/3`, `'#='(X, Y, Truth)`, `clpz_t/2`) over low-level evaluation (`is/2`, `>/2`). Always post domain declarations (`ins`, `in`) before posting complex relations to enable early constraint propagation. Link model flags via `#<==>` (e.g. `X #> 10 #<==> B #= 1`) and pass partial closures `(#<)(0)` to `tfilter/3`.
79
-
11.**Coroutining & Goal Suspension**: Use `freeze/2` for single-variable activation guards (`nonvar/1`) and `when/2` for multi-variable or disjunctive activation conditions (`(nonvar(A) ; nonvar(B))`). Prefer CLP(Z)/`dif/2` over manual coroutining where domain-specific constraints apply.
80
-
12.**Clean Data Representations**: Prefer clean data structures where element kinds are distinguished by principal functor (`leaf(L)` vs `node(L, R)`). Avoid defaulty representations that force runtime type tests (`var/1`) or procedural default branches. Convert raw input data into clean trees early.
81
-
13.**Macro & Compile-Time Expansion**: Use Prolog's macro mechanism (`user:term_expansion/2` and `user:goal_expansion/2`) to transform clauses or rewrite inline goals at compile time to eliminate boilerplate and redundant rules. Prefer static compile-time expansion over dynamic database modification (`asserta`/`assertz`).
82
-
14.**Avoid Non-Standard Extensions**: Do not rely on engine-specific types (e.g. SWI dicts or SWI string types) when writing standard Prolog code.
83
-
15.**Library Steering vs Reading Source**: Rely on dialect-specific Standard Library Cheat Sheets for module header declarations and predicate exports. AI assistants MUST NOT read raw standard library implementation source files, relying instead on concise cheat sheets and pre-trained semantics to save context tokens.
84
-
16.**Safety**: Execute code using `prolog-safe`.
85
-
86
-
17.**Prolog Tooling in Prolog (ISO Core + Engine Shims)**: Programs that parse, rewrite, transform, analyze, or generate Prolog source code SHOULD themselves be implemented in Prolog, exploiting the language's homoiconicity (code = terms = data). Structure such tools using an ISO-common core with flat, engine-specific shim files:
77
+
9.**Meta-Predicate Declarations (`meta_predicate`)**: When defining predicates in a module that accept callable arguments (goals `0`, closures `1`..`N`, DCG rules `//` or `2`, or module-sensitive terms `:`), ALWAYS insert a `:- meta_predicate` declaration directly after the `:- module/2` header and imports. This ensures the module system applies caller-module name expansion to meta-arguments across module boundaries:
78
+
```prolog
79
+
:- module(my_combinators, [
80
+
my_maplist/3,
81
+
my_tfilter/3,
82
+
bracketed//3
83
+
]).
84
+
85
+
:- meta_predicate
86
+
my_maplist(2, +, -),
87
+
my_tfilter(2, +, -),
88
+
bracketed(//, //, //, ?, ?).
89
+
```
90
+
- Use exact closure arities: `0` for goals (`call(G)`), `1`..`9` for closures expecting additional arguments (`call(C, X)` -> `1`, `call(C, X, Y)` -> `2`), `//` (or `2`) for DCG rules.
91
+
- Use `+`, `-`, `?`, `*` for non-meta data terms. NEVER declare `meta_predicate` on first-order data predicates or mark data arguments as `:`/`0` (which would trigger unwanted module qualification wrapping).
92
+
10.**Explicit Library Declarations**: Always explicitly import required library modules (e.g. `:- use_module(library(reif)).`, `:- use_module(library(dcgs)).`, `:- use_module(library(charsio)).`, `:- use_module(library(lambda)).`, `:- use_module(library(clpz)).`). Do not assume SWI-style autoloading when targeting ISO or embedded engines.
93
+
11.**Control Structures & CLP(Z) Constraints**: Use standard ISO control structures `(,)/2`, `(;)/2`. Prefer CLP(Z) constraints (`#=`, `#>`, `all_distinct/1`) and reified arithmetic (`zcompare/3`, `'#='(X, Y, Truth)`, `clpz_t/2`) over low-level evaluation (`is/2`, `>/2`). Always post domain declarations (`ins`, `in`) before posting complex relations to enable early constraint propagation. Link model flags via `#<==>` (e.g. `X #> 10 #<==> B #= 1`) and pass partial closures `(#<)(0)` to `tfilter/3`.
94
+
12.**Coroutining & Goal Suspension**: Use `freeze/2` for single-variable activation guards (`nonvar/1`) and `when/2` for multi-variable or disjunctive activation conditions (`(nonvar(A) ; nonvar(B))`). Prefer CLP(Z)/`dif/2` over manual coroutining where domain-specific constraints apply.
95
+
13.**Clean Data Representations**: Prefer clean data structures where element kinds are distinguished by principal functor (`leaf(L)` vs `node(L, R)`). Avoid defaulty representations that force runtime type tests (`var/1`) or procedural default branches. Convert raw input data into clean trees early.
96
+
14.**Macro & Compile-Time Expansion**: Use Prolog's macro mechanism (`user:term_expansion/2` and `user:goal_expansion/2`) to transform clauses or rewrite inline goals at compile time to eliminate boilerplate and redundant rules. Prefer static compile-time expansion over dynamic database modification (`asserta`/`assertz`).
97
+
15.**Avoid Non-Standard Extensions**: Do not rely on engine-specific types (e.g. SWI dicts or SWI string types) when writing standard Prolog code.
98
+
16.**Library Steering vs Reading Source**: Rely on dialect-specific Standard Library Cheat Sheets for module header declarations and predicate exports. AI assistants MUST NOT read raw standard library implementation source files, relying instead on concise cheat sheets and pre-trained semantics to save context tokens.
99
+
17.**Safety**: Execute code using `prolog-safe`.
100
+
101
+
18.**Prolog Tooling in Prolog (ISO Core + Engine Shims)**: Programs that parse, rewrite, transform, analyze, or generate Prolog source code SHOULD themselves be implemented in Prolog, exploiting the language's homoiconicity (code = terms = data). Structure such tools using an ISO-common core with flat, engine-specific shim files:
87
102
-**ISO core** (`core.pl`): All term reading (`read_term/2`), DCG-based traversal and transformation, `copy_term/2`, `functor/3`, `=..`, and CLP(Z) constraints. This layer MUST NOT use engine-specific predicates or library paths.
88
103
-**Flat shim files** (`scryer_shim.pl`, `swi_shim.pl`, `trealla_shim.pl`, etc.): Each shim defines only what differs per engine — module load paths, flag names, engine-specific built-ins — and exports a uniform interface consumed by the core.
89
104
-**Entry point** (`run.pl`): Selects and loads the appropriate shim (e.g. via `PROLOG_ENGINE` flag or conditional compilation), then loads `core.pl`.
Avoid duplicating DCG rules just to vary an element non-terminal or predicate. Use `call//N` to parameterize grammar rules:
106
+
Avoid duplicating DCG rules just to vary an element non-terminal or predicate. Use `call//N` to parameterize grammar rules, and declare `:- meta_predicate` with `//` or `2` so closures resolve in the caller module context:
107
107
108
108
```prolog
109
+
:- module(seq_combinators, [
110
+
seq_of//2
111
+
]).
112
+
113
+
:- meta_predicate
114
+
seq_of(?, //, ?, ?).
115
+
109
116
% Generic DCG rule to match a list of elements using a parameter non-terminal nonterm//1
[](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fgithub.com%2Fdougransom%2Fprolog-agent-toolkit)
9
9
10
-
**Version**: `0.0.1.dev17`
10
+
**Version**: `0.0.1.dev18`
11
11
**Category**: AI Assistant Developer Tools / Prolog Language Tooling
0 commit comments