Skip to content

Conversation

@jjtolton
Copy link

@jjtolton jjtolton commented Oct 22, 2025

Summary

This PR adds support for dyadic quad syntax to Scryer Prolog's loader, enabling test specifications with labeled queries.

Motivation

This is inspired by Ulrich Neumerkel's quad notation for Prolog testing:

Changes

1. Parser (src/parser/ast.rs)

  • Added infix operator definition for ?- (xfx, 1200)
  • Allows parsing of dyadic quad syntax: Label ?- Query

2. Loader (src/loader.pl)

  • Modified load_loop to recognize dyadic quads (_ ?- _Query)
  • Modified devour_answer_descriptions to handle dyadic quads recursively
  • Dyadic quads and their answer descriptions are now properly skipped during loading

Syntax Supported

Monadic quads (already supported):

?- my_append([1,2], [3,4], Xs).
   Xs = [1,2,3,4].

Dyadic quads (NEW):

"Test append" ?- my_append([1,2], [3,4], Xs).
   Xs = [1,2,3,4].

Testing

Tested with the quads package: https://github.com/jjtolton/quads

Example files that now load correctly:

  • Dyadic quads with string labels followed by answer descriptions
  • Mixed monadic and dyadic quads in the same file

Important Note

This is a proof-of-concept implementation only. The author acknowledges that someone more experienced with Scryer Prolog internals should review and potentially reimplement this functionality properly. This PR serves to demonstrate that the feature is feasible and useful.

Related

🤖 Generated with Claude Code

Co-Authored-By: Claude noreply@anthropic.com

jjtolton and others added 3 commits October 21, 2025 19:06
This commit adds support for the binary quad test syntax alongside the
existing monadic quad syntax. Previously, Scryer Prolog only supported:

    ?- my_pred(X).
       X = value.

With this change, it now also supports the more concise binary format:

    my_pred(X) ?- X = value.

The loader now recognizes and skips binary quad terms (Goal ?- Answer)
during file loading, preventing them from being compiled as regular
clauses. This eliminates the 'permission_error(modify,static_procedure)'
errors that occurred when the binary operator attempted to define
clauses for built-in operators like =/2.

Both syntaxes can coexist in the same file and are handled by external
test frameworks that process these quad annotations.
To support the binary quad syntax (Goal ?- Answer), we need ?- to be
recognized as an infix operator in addition to its existing prefix form.

This mirrors how :- is defined as both prefix and infix, allowing it to
be used for both directives (:- directive) and clauses (Head :- Body).

Now ?- can be used for:
- Prefix form (traditional): ?- query.
- Infix form (binary quads): goal ?- answer.
- Added binary quad check in devour_answer_descriptions
- Binary quads with format "Label" ?- Query followed by answer lines
  are now properly recognized and their answers ignored
- Fixes issue where answer descriptions were being compiled as facts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@bakaq
Copy link
Contributor

bakaq commented Oct 22, 2025

I don't think having ?- as an infix operator by default is a good idea. One very good point of Scryer Prolog in my opinion is that is comes with just the ISO Prolog operators by default. You can add support for binary quads without the operator just fine, and users can define the operator themselves if they want.

@jjtolton
Copy link
Author

jjtolton commented Oct 22, 2025

I don't think having ?- as an infix operator by default is a good idea. One very good point of Scryer Prolog in my opinion is that is comes with just the ISO Prolog operators by default. You can add support for binary quads without the operator just fine, and users can define the operator themselves if they want.

Oh yeah? Then how do you explain this: https://www.complang.tuwien.ac.at/ulrich/iso-prolog/length_quad.pl

(for the record I agree in the sense that I would've done this entirely as a package, but there's no way that I know of to support dyadic quads with an external "patch" to scryer, need to modify source directly as far as I know. Maybe it could be done with a crate?)

@jjtolton jjtolton changed the title Add binary quad syntax support (proof of concept) Add dyadic quad syntax support (proof of concept) Oct 22, 2025
… prefix directives

This ensures that prefix ?- (directives) at precedence 1200 takes priority over infix ?- (dyadic quads) at precedence 1199, preventing parsing ambiguities.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link

@UWN UWN left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you give an example where such an ambiguity might arise? Typically, there is a problem with infix versus postfix. That's why there is such a restriction in 6.3.4.3. See also Note 4.

@jjtolton
Copy link
Author

Could you give an example where such an ambiguity might arise? Typically, there is a problem with infix versus postfix. That's why there is such a restriction in 6.3.4.3. See also Note 4.

I have no immediate evidence it would be a problem but the situation that concerns me is some scenario where

:- use_module(library(lists)).

?- X=1.
   X=1.

could be interpreted as

((:- use_module(library(lists))) ?- X=1)

although as I am typing this I realize that the . would fairly definitively prevent that from occurring. 🤔

Perhaps overly defensive. I should more thoroughly review the priorities given to operators.

This reverts the precedence change, setting both prefix and infix ?-
operators back to 1200 to match the :- operator definition.
@UWN
Copy link

UWN commented Oct 23, 2025

Perhaps overly defensive. I should more thoroughly review the priorities given to operators.

Your example needs to be modified a bit. By "forgetting" an end-dot for a fact, we then get:

fact(nimporte) /* forgotten dot */

?- true.
   true.

On the other hand, the lowered priority of the infix ?- now leads to the following confusions:

a :-
   b,
   c /* forgotten dot */ 

?- true.

What would be in fact more important is a better indication of syntax errors (#302).

And in general, I am not too happy that these quad-discussions start now, because there is a significant backlog w.r.t. digit separators and the double bar notation. As long as these are not fixed, it does not make much sense to look into further steps for quads.

jjtolton added a commit to jjtolton/scryer-prolog that referenced this pull request Oct 24, 2025
Implements the digit separator specification from:
https://www.complang.tuwien.ac.at/ulrich/iso-prolog/digit_separators

Changes:
- Add digit separator support (underscore with optional whitespace/comments)
  for hexadecimal (0x), octal (0o), and binary (0b) number literals
- Decimal numbers already had digit separator support
- Add helper functions: skip_underscore_in_hexadecimal/octal/binary
- Update hexadecimal_constant, octal_constant, and binary_constant functions

Tests:
- Add 16 Rust unit tests in src/tests/parse_tokens.rs
- Add 18 Prolog integration tests in src/tests/digit_separators.pl
- Add CLI test configuration in tests/scryer/cli/src_tests/digit_separators.toml
- All tests verify: basic underscores, multiple underscores, whitespace after
  underscores, and comments between digits

Examples:
  0xDE_AD, 0xFF_ 00, 0xDE_ /* comment */ AD
  0o7_6, 0o77_ 00, 0o1_ /* octal */ 23
  0b10_11, 0b1111_ 0000, 0b10_ /* binary */ 11

Reference: mthom#3132 (comment)
@jjtolton jjtolton changed the title Add dyadic quad syntax support (proof of concept) Add dyadic quad syntax support Oct 24, 2025
@jjtolton
Copy link
Author

And in general, I am not too happy that these quad-discussions start now, because there is a significant backlog w.r.t. digit separators and the double bar notation. As long as these are not fixed, it does not make much sense to look into further steps for quads.

Is there more of this backlog? Do you mean what is one the Scryer issues board or something else?

@UWN
Copy link

UWN commented Oct 25, 2025

Is there more of this backlog? Do you mean what is one the Scryer issues board or something else?

Currently, I am looking just at digit separators. That is, I am waiting currently for updates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants