Circular predicate usage from different modules. #2992
-
I am trying to learn Prolog by writing some random stuff. Currently I am implementing a simple parser. I have modules :- module(string, [string/3]).
:- use_module(library(dcgs)).
:- use_module(expression, [expression/3]).
string(string_node(Parts)) -->
"'",
string_(Parts),
"'".
string_([Part | Parts]) -->
(
interpolated_expression(Part)
; static_character(Part)
),
string_(Parts).
interpolated_expression(Part) -->
"${",
expression(Part),
"}".
static_character(Character) -->
[Character],
{
Character \= '\'',
Character \= '$'
}. :- module(expression, [expression/3]).
:- use_module(library(dcgs)).
:- use_module(string, [string/3]).
expression(Node) -->
string(Node). Unfortunately, there is a cyclic dependency :- module(string, [string/4]).
:- use_module(library(dcgs)).
string(Functor, string_node(Parts)) -->
"'",
string_(Functor, Parts),
"'".
string_(Functor, [Part | Parts]) -->
(
interpolated_expression(Functor, Part)
; static_character(Part)
),
string_(Functor, Parts).
interpolated_expression(Functor, Part) -->
"${",
{ E =.. [Functor, Part] },
E,
"}".
% Bottom part of the code is identical. But Scryer complains that P.S.: I omitted some code for brevity to highlight the problem and to not introduce unnecessary complications to the examples. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 7 replies
-
Could you please include the exact query you used and the exact error Scryer yields? Thank you a lot! |
Beta Was this translation helpful? Give feedback.
It seems this is one of the very first use cases of higher-order
phrase//N
non-terminals! Very nice!First, why the existence error? It occurs because
expression/3
is not available in the context of thestring
module. No problem, we can make Scryer automatically add the required module-qualification with ameta_predicate/1
declaration in modulestring
:When we do this, then Scryer will automatically add the required module-prefix, and it will be as if you had written the invocation of
string//2
as:string(expression:expression, Node).
But then we get:
…