Перевод на DCG Semicontext не работает - следите за - PullRequest
0 голосов
/ 04 марта 2019

В качестве ответа на этот вопрос , который ставит проблему

Возвращает количество элементов в списке, но если два одинаковых элемента расположены рядом друг с другом, то неувеличить счетчик.

Этот код наиболее близок к решению с помощью DCG и полуконтекста.

lookahead(C),[C] -->
    [C].

% empty list
% No lookahead needed because last item in list.
count_dcg(N,N) --> [].

% single item in list
% No lookahead  needed because only one in list.
count_dcg(N0,N) -->
    [_],
    \+ [_],
    { N is N0 + 1 }.

% Lookahead needed because two items in list and
% only want to remove first item.
count_dcg(N0,N) -->
    [C1],
    lookahead(C2),
    { C1 == C2 },
    count_dcg(N0,N).

% Lookahead needed because two items in list and
% only want to remove first item.
count_dcg(N0,N) -->
    [C1],
    lookahead(C2),
    {
        C1 \== C2,
        N1 is N0 + 1
    },
    count_dcg(N1,N).

count(L,N) :-
    DCG = count_dcg(0,N),
    phrase(DCG,L).

Как правильно решить проблему, используяDCG с полуконтекстом на заголовке предложения?

Хотелось бы узнать, возможно ли изменение с полуконтекстом на заголовке предложения?Если возможно, тогда нужен рабочий пример кода, если не возможно, то требуется пояснение.

Ответы [ 2 ]

0 голосов
/ 05 марта 2019

Я думаю, что это правильно использует полуконтекстную запись.Я считаю, используя 0,s(0),...

% Constraint Logic Programming
:- use_module(library(dif)).    % Sound inequality
:- use_module(library(clpfd)).  % Finite domain constraints

list([])     --> [].
list([L|Ls]) --> [L], list(Ls).

state(S), [state(S)] --> [state(S)].
state(S, s(S)), [state(s(S))] --> [state(S)].

keep_state(S,I),[state(S)] --> [state(S)],[I].
end_state(S)  -->[state(S)],[].

lookahead(C),[S,C] -->
    [S,C].

count_dcg(S,S) --> 
    state(S), %might not need this
    end_state(S).

/* Can be used get the length of a list
count_dcg(S,S2) --> 
    state(S,S1),
    keep_state(S1,_),
    count_dcg(S1,S2),
    {}.
*/

%last item.
count_dcg(S,S1) -->     
    state(S,S1),
    keep_state(S1,_C),
    list(R),
    {R = [state(_)]}.

%Two the same dont increase state 
count_dcg(S,S1) -->
    state(S), %might not need this
    keep_state(S,C1),
    lookahead(C1),
    count_dcg(S,S1).

%Two different increase state  
count_dcg(S,S2)  -->
    state(S,S1),
    keep_state(S1,C1),
    lookahead(C2),
    {
        dif(C1,C2)
    },
    count_dcg(S1,S2).

count(L,S) :-
    phrase(count_dcg(0,S),[state(0)|L]).

Это не работает так же хорошо, как я надеялся на такие случаи, как:

65 ?- count([a,b,X,c],L).
X = b,
L = s(s(s(0))) ;
;
X = c,
L = s(s(s(0))) .

Вы можете конвертировать peano с помощью:

natsx_int(0, 0). 
natsx_int(s(N), I1) :- 
  I1 #> 0, 
  I2 #= I1 - 1, 
  natsx_int(N, I2).

или вы можете изменить предикаты состояния:

state(S), [state(S)] --> [state(S)].
state(S, S2), [state(S2)] --> [state(S)],{S2#=S+1}.
0 голосов
/ 04 марта 2019

Как насчет:

:-use_module(library(clpfd)).

list([])     --> [].
list([L|Ls]) --> [L], list(Ls).

lookahead(C),[C] -->
    [C].

count_dcg(N,N) --> [].
count_dcg(N0,N) --> %last item.
    [_],
    list(R),
    {R = [], N #=N0+1}.
count_dcg(N0,N) -->
    [C1],
    lookahead(C1),
    count_dcg(N0,N).
count_dcg(N0,N) -->
    [C1],
    lookahead(C2),
    {
        dif(C1,C2),
        N1 #= N0 + 1
    },
    count_dcg(N1,N).

count(L,N) :-
    phrase(count_dcg(0,N),L).
...