Если вы хотите видеть только все сгенерированные предложения, очень удобно использовать следующее:
?- length(Xs, N), phrase(mynonterminal, Xs).
Конечно, это генерирует все предложения. Но это очень полезно, и это экономит ваше время, чтобы подумать о конкретном пределе. Если вы хотите ограничить это, добавьте цель between(0,10,N)
впереди.
Если вы хотите сказать в грамматике, что определенный нетерминал должен занимать определенную длину, лучше сказать это явно:
seq([]) --> [].
seq([E|Es]) --> [E], seq(Es).
a --> {length(Es,10)}, seq(Es), {phrase(mynonterminal,Es)}.
Если вы все еще не счастливы, то вы хотите выразить пересечение двух нетерминалов. Это равносильно тому, чтобы просить пересечение двух контекстно-свободных языков, что в общем случае неразрешимо. Но гораздо раньше у вас будут проблемы с терминацией. Так что помните об этом в следующем:
:- op( 950, xfx, &).
(NT1 & NT2) -->
call(Xs0^Xs^(phrase(NT1,Xs0,Xs),phrase(NT2,Xs0,Xs))).
Следующее необходимо, только если вы не используете library (lambda) :
^(V0, Goal, V0, V) :-
call(Goal,V).
^(V, Goal, V) :-
call(Goal).
Итак, теперь вы можете выразить пересечение двух нетерминалов. Но, пожалуйста, имейте в виду, что завершение здесь очень хрупкое. В частности, завершение первого нетерминала не обязательно ограничивает второе.