2

次のリストを検討してください。

[my、name、is、jack、baur]

これを次のパターンに統合したいと思います。

[my、name、is、Name]

そのため、変数Nameの値は最終的に「jackbaur」になります。変数はここではある種のワイルドカードとして機能しており、不明な数のアトム/リストメンバーと統合する必要があります。

重要:

  • 変数/ワイルドカードが常に最後にあるとは限りません
  • 複数の変数/ワイルドカードが存在する可能性があります

現在、私はこのようなものを持っています:

rule([my,name,is,Name],[hello,Name]).

% Sentence is a list (e.g. [my,name,is,jack,baur]
answer(Sentence,Response) :-
    rule(Sentence,ResponseList),
    atomic_list_concat(ResponseList,' ',Response).

明らかに、これNameは、が2つではなく、正確に1つの単語である場合にのみ機能します。

Prologでこの問題にどのようにアプローチしますか?

4

2 に答える 2

1

次のようなカスタム統合アルゴリズムが必要です。

unify([], []).
unify([X|L], R) :-
    (var(X) ->
        % unify the variable X with some prefix of R
        append(X, Tail, R),
    ;
        R = [X|Tail],
    ),
    unify(L, Tail).

使用法:

1 ?- unify([i, am, a, Profession, and, i, Verb, it],
           [i, am, a, prolog, programmer, and, i, like, it]).
Profession = [prolog, programmer],
Verb = [like].

このアルゴリズムではL、効率を上げるために変数のみを使用できます。原子を貼り付ける問題は、すでに解決しているように見えるので、お任せします。

現在のバージョンでは変数がゼロアトムに一致することが許可されていますが、それを禁止する制約を簡単に追加できることに注意してください。

于 2012-12-25T14:08:21.613 に答える
1

ここでDCGの可能性。かなりきれいだと思います。

list(L) --> {length(L, _)}, L.

rule(R) -->
    [my, name, is], list(Name),
    [and, i, live, in], list(Country),
    {flatten([hello, Name, of, Country],R)}.

rule([hello|Name]) -->
    [my, name, is], list(Name) .

answer(Sentence, Response) :-
    phrase(rule(Response), Sentence), !.

それと

?- answer([my, name, is, bill, the, kid, and, i, live, in, new, york],R).
R = [hello, bill, the, kid, of, new, york].

ここでの重要な生成はlist//1であり、これはトークンの任意の長さのリストと一致します。

注意:list(A),list(B),、 AとBの両方がバインドされていない場合は避けてください。代わりに、のように間にトークンがある場合は問題ありませんlist(A),[and],list(B),

于 2012-12-26T11:28:01.237 に答える