Я пытаюсь создать язык a ^ nb ^ n-1 c ^ n-2, используя DCG, но не могу сделать succ (0) для обработки n - PullRequest
0 голосов
/ 03 декабря 2018
s(Count) --> a(Count), b(Count), c(Count).

a(0) --> [].
a(succ(Count)) --> [a], a(Count).

b(0) --> [].
b(succ(succ(Count))) --> [b], b(Count).

c(0) --> [].
c(succ(succ(succ(Count)))) --> [c], c(Count).

Что ж, легко создать такой язык, как ^ nb ^ nc ^ n, используя succ (0) для каждого правила, но когда дело доходит до изменения n для каждого блока ab и c, это не работает.

Ответы [ 3 ]

0 голосов
/ 03 декабря 2018

Глядя на ваши предложения, как:

c(0) --> [].
c(succ(succ(succ(Count)))) --> [c], c(Count).

Обратите внимание, что вы соответствуете только два случая - ноль или три символа, но как насчет одного или двух?Изменение c для учета каждой приемлемой длины кажется тупиковым, однако гораздо проще указать, сколько c s вы хотите, относительно вашего числа a s и b s в месте, где вы управляете имивсе, что находится в s:

s(succ(succ(Count))) --> a(succ(succ(Count))), b(succ(Count)), c(Count).

Это, естественно, соответствует вашей спецификации: для N из как минимум двух принимайте N a с, N-1 b си N-2 c с.

Теперь все остальное легко встает на свои места:

a(0) --> [].
a(succ(Count)) --> [a], a(Count).

b(0) --> [].
b(succ(Count)) --> [b], b(Count).

c(0) --> [].
c(succ(Count)) --> [c], c(Count).

Конечно, вы можете заменить их общим предложением char(Char, Count) (оставленным какупражнение).

?- phrase(s(succ(succ(succ(0)))), X).
X = [a, a, a, b, b, c].
0 голосов
/ 04 декабря 2018

В дополнение к ответу @firefrorefiddle я бы хотел отметить три вещи.Во-первых, при использовании чисел Пеано более привычно использовать функтор s / 1 для обозначения преемника и одну букву, такую ​​как X, для переменной, таким образом получая меньшие члены:

s(X)            succ(Count)
s(s(X))         succ(succ(Count))
s(s(s(X)))      succ(succ(succ(Count)))
s(s(s(s(X))))   succ(succ(succ(succ(Count))))
.               .
.               .
.               .

Во-вторых, для дальнейшегоулучшить читабельность, тогда было бы выгодно выбрать другое имя для DCG, может быть что-то вроде language // 1 вместо s // 1.И в-третьих, вместо написания одних и тех же DCG-правил для a, b и c, вы можете определить более общую DCG, которая позволит вам указать элемент и его номер вхождения в списке.Собрав все это вместе, ваш DCG может выглядеть примерно так:

language(s(s(X))) -->
   element_frequency(a,s(s(X))),
   element_frequency(b,s(X)),
   element_frequency(c,X).

element_frequency(_E,0) -->
   [].
element_frequency(E,s(X)) -->
   [E],
   element_frequency(E,X).

В приведенном выше языке кода // 1 соответствует s // 1 в вашем коде, а element_frequency // 2 является заменой для // 1, b // 1 и c // 1.Если вы сделаете запрос к этой DCG, вы обнаружите, что она по-прежнему выдает те же ответы, что и в посте @ firefrorefiddle, например:

   ?- phrase(language(s(s(s(0)))),L).
L = [a,a,a,b,b,c]
0 голосов
/ 03 декабря 2018

[] DCG совпадает в любое время.Давайте перевернем правила a, b, c.

s(Count) --> a(Count), b(Count), c(Count).

a(succ(Count)) --> [a], a(Count).
a(0) --> [].

b(succ(succ(Count))) --> [b], b(Count).
b(0) --> [].

c(succ(succ(succ(Count)))) --> [c], c(Count).
c(0) --> [].

:- s(N,[a,a,a,a,a,a,b,b,b,c,c],[]),writeln(N).
:- halt.
...