1

プロローグの宿題があります。さまざまな国籍 (フランス語、英語、ポーランド語、イタリア語、トルコ語) の円卓に 5 人が座っています。彼らはそれぞれ、自分の言語以外に 1 つの言語しか知りません。彼らはそれぞれが2人の隣人と話すことができるように円卓に着きます(1人の隣人とは母国語で話し、もう1人は彼らが知っている1つの外国語で話します)。イギリス人はイタリア語を知っていて、ポーランド人はフランス語を知っていて、トルコ人は英語を知らない。問題は、トルコ人が知っている外国語は何語かということです。

節と述語だけを使って何かをしたことがありますが、行き止まりになりました。先生は、最も簡単な方法はリストを使用することだと提案しました。

そのリストに何が含まれるか、またはコードのアイデアについて何か考えはありますか?

更新 (弱いロジック コード):

    predicates
knowTheLanguage(symbol,symbol)  
knowNotTheLanguage(symbol,symbol)
isNeighbor(symbol,symbol,symbol,symbol)

aTheory(symbol,symbol,symbol,symbol) 
anotherTheory(symbol,symbol,symbol,symbol)

    clauses
knowTheLanguage(englishman,italian).
knowTheLanguage(polishman,franch).

%native tongues
knowTheLanguage(englishman,english).
knowTheLanguage(frenchman,franch).
knowTheLanguage(polishman,polish).
knowTheLanguage(italianman,italian).
knowTheLanguage(turk,turkish).


knowNotTheLanguage(turk,english).

aTheory(centralPerson, languageCntrlPers, personOnOneSide,languagePrsnOnOneSide) if knowTheLanguage(personOnOneSide,languageCntrlPers)
                                                                            and not( knowTheLanguage(centralPerson,languagePrsnOnOneSide))
                                                                            and not(knowNotTheLanguage(centralPerson,languagePrsnOnOneSide)).
anotherTheory(centralPerson, languageCntrlPers, personOnOneSide,languagePrsnOnOneSide) if knowTheLanguage(centralPerson,languagePrsnOnOneSide) 
                                                                            and  not( knowTheLanguage(personOnOneSide,languageCntrlPers))
                                                                            and not(knowNotTheLanguage(centralPerson,languagePrsnOnOneSide)).

isNeighbor(centralPerson, languageCntrlPers, personOnOneSide,languagePrsnOnOneSide) if aTheory(centralPerson, languageCntrlPers, personOnOneSide,languagePrsnOnOneSide)
                                                                        or
                                                                        anotherTheory(centralPerson, languageCntrlPers, personOnOneSide,languagePrsnOnOneSide).

更新 - プログラミング環境: ボーランドによるターボ プロローグ 2.0 '86、'88、また私はプロローグの完全な初心者なので...少なくともプログラムの完全なスケッチとコード本体の外側の説明を高く評価します。私は物事をゆっくりと処理します:D

4

3 に答える 3

1

循環リストを操作できます。このコードを試して理解してください。

t :-
    L = [1,2,3 | L],
    my_write(5, L).

my_write(0, _).
my_write(N, [H | T]) :-
    write(H), nl,
    N1 is N - 1,
    my_write(N1, T).

巡回リストは非常に便利です。

リストの要素は何か、言語の制約は何かを説明してください

編集:これが私の解決策であり、SWI-Prologで動作します:

% @arg1 : list of nationalities around the table
% @arg2 : list of persons
dinner(Languages, Table) :-
    length(Languages, Len),
    length(Table, Len),

    % set Natianalities and languages
    init_1(Table, Languages, Languages),

    % create cyclic list
    % works with SWI-Prolog
    append(Table, L, L),

    % set languages constraint
    init_2(Len, L).

init_1([], [], []).

init_1([person(N, L) | T], Nations, Languages):-
    select(N, Nations, New_Nations),

    % problem specific
    (   N = english
    ->  L = italian
    ;   N = polish
    ->  L = french
    ;   true),

    select(L, Languages, New_Languages),

    % problem specific
    (   N = turkish
    ->  L \=  english
    ;   true),

    init_1(T, New_Nations, New_Languages).

% persons speaks with theirs two neighbors
init_2(Tr, [person(_N1, L1), person(N2, L2), person(N3, L3) | T]) :-
    Tr > 0,
    member(N2, [L1, L3]),
    Tr1 is Tr - 1,
    init_2(Tr1, [person(N2, L2), person(N3, L3) | T]).

init_2(0, _).
于 2012-11-09T11:10:36.883 に答える
0

通常、私は制約を使用してそのようなパズルを解きますが、それはおそらくあなたの宿題にはあまりにも進んでいるでしょう。したがって、制約を使用して検索スペースを制限する代わりに、テストを使用してソリューションが実行可能かどうかを確認する必要があります。

Peopleたとえばとの2つのリストを操作する必要がありますLanguages。リストの各要素は、テーブルの1つの座席に対応します。両方のリストに同じドメインを含めることができます[f,e,p,i,t]。ドメインのセマンティクスは明確である必要があります。

ソリューションを生成するには、最初にリストを設定し、次にリストをインスタンス化し、インスタンス化が制約を満たしているかどうかを確認します。

puzzle(People, Languages) :-
    Domain = [f,e,p,i,t],
    length(People, 5),
    length(Languages, 5),
    % symmetry break:
    People = [f|_],
    % instantiate People
    people(People, Domain),
    % instantiate languages and check constraints
    languages(Languages, People, Domain).

リストの最初の要素Peopleがに設定されていることに注意してくださいf。これは、テーブルが丸いために返されるシンメティックソリューションを除外するためです。この制限がなければ、各ソリューションには4つの追加の対称ソリューションがあります。

読む前にあなた自身の解決策を考え出してみてください...:-)

リストPeopleが最初にインスタンス化されます。各要素が1回だけ表示されるように注意する必要があります。

people([], []) :- !.
people([P|RestP], Domain) :-
    delete(P, Domain, RestD),
    people(RestP, RestD).

Prologの方言はのselect/3代わりに持っているかもしれませんdelete/3

リストをインスタンス化するときLanguagesに、パズルの制約に違反していないことも確認します。

languages(Languages, People, Domain) :-
    Term =.. [[]|People],
    languages0(Languages, People, Term, 1, Domain).
languages0([], _, _, _, _) :- !.
languages0([L|RestL], [P|RestP], Term, I, Domain) :-
    delete(L, Domain, RestD),
    L \= P, % language needs to be foreign
    check_l(P, L),
    check_n(L, I, Term),
    I1 is I+1,
    languages0(RestL, RestP, Term, I1, RestD).

繰り返しますが、各要素は1回だけ表示できます。

check_l外国語に関する制約をチェックします。

check_l(e, i).
check_l(p, f).
check_l(t, L) :- L \= e.
check_l(f, _).
check_l(i, _).

check_n左隣または右隣の言語と国籍が一致することを保証します。

check_n(L, I, Term) :-
    ( I == 1 -> NL = 5 ; NL is I-1 ),
    ( I == 5 -> NR = 1 ; NR is I+1 ),
    ( arg(NL, Term, L) ; arg(NR, Term, L) ).

2つの解決策があります:

?- puzzle(P, L).
P = [f, e, i, t, p]
L = [e, i, t, p, f]
Yes (0.00s cpu, solution 1, maybe more)
P = [f, p, t, i, e]
L = [e, f, p, t, i]
Yes (0.01s cpu, solution 2, maybe more)
No (0.01s cpu)
于 2012-11-09T15:02:33.557 に答える
0

一般に、問題をモデル化するときは、無関係な詳細を排除してコンパクトな表現を特定することが重要です。ここで、たとえばpolishmanandpolishは役に立ちません。それが人間と言語の両方polishを表していることに同意できます。

ソリューションをスケッチします。省略記号を記入して、制約を追加してください。

puzzle(L) :-
    L = [P1,P2,P3,P4,P5],
    cadj(P5,P1,P2),
    ...
    member(p(english, italian), L),
    member(p(french,  _ ),      L),
    ...
    \+ member(p(turk, english), L).

% constrain adjacents
cadj(p(Pl, Ll), p(P, K), p(Pr, Lr)) :-
    P = Ll, K = Pr ; P = Lr, K = Pl.

p/2 は、男性と彼が知っている言語を表します。cadj/3 は、左の人が私の言語を知っているなら、私は右の人の言語を知っているにちがいない、またはその逆であると言っています。

必要な言語を取得するには、試してください

puzzle :-
    puzzle(L),
    memberchk(p(turk, T), L),
    writeln(T:L).

他にも解決策はありますが、言語Tは一貫して単一の値に制限されています...

于 2012-11-09T18:13:56.017 に答える