3

部屋に5人います。人々が幸せか悲しいかを判断するためのルールを書きます。しかし、それを始める前に、私は 5 人のうち正確に 3 人が幸せで 2 人が悲しいという基本的な知識を持っています。したがって、これに基づいて演繹を行うことは可能であるはずです: もし - とにかく - 幸せな 3 人が誰であるかを知っていれば、2 人の悲しい人を推測することができ、その逆も成り立ちます。

私がこれまでに得たものは次のとおりです。

person(bob).
person(tim).
person(steve).
person(roy).
person(jack).

sad(bob).
sad(tim).

happy(X) :-
  person(X),
  \+ sad(X),
  findall(Y, sad(Y), YS),
  length(YS, 2).

尋ねられたときhappy(X)、プロローグはロイ、スティーブ、ジャックをくれます。問題: とsad/1の相互再帰のため、同じ方法でルールを定義できませんhappy/1。上記の例の結果が同じままであるようなルールを追加できるようにしたいのですが、次の初期化では Bob と Tim が悲しいものとしてリストされます。

person(bob).
person(tim).
person(steve).
person(roy).
person(jack).

happy(steve).
happy(roy).
happy(jack).

これについて考えるべき良い方法はありますか?5 が 3 つの幸せと 2 つの悲しいに分割されるという知識に基づいて演繹が可能であるという事実を超えて、追加のロジックを追加して、後でsad/1andのルールをさらに記述できるようにすることが重要です。happy/1

4

2 に答える 2

0

論理を整理することは、一貫性の問題であり、特定の述語または事実の矛盾する意味を回避することです。

の定義sad/1は現在、クエリへのバックトラックごとに 1 つの結果が得られるという事実ですsad(X)。しかし、あなたの定義はhappy/1リストを生成します。これにより、リストを生成するためにどのように定義したいかが残ります。これは、引数が悲しい人である場合に真であるクエリとしてのsad/1現在の定義と競合します。sad/1

より一貫したアプローチは、 がhappy/1動作するように動作するように定義することsad/1です。

happy(X) :-
    person(X),
    \+ sad(X).

次に、リストのバージョンを定義できます。

happy_all(A) :-
    findall(X, happy(X), A).

sad_all(A) :-
    findall(X, sad(X), A).

person/1上記は、すべての有効な人々の宇宙sad/1を定義し、悲しい人が誰であるかを定義する明確な事実があることを前提としています。また、人が悲しんでいない場合、幸せに違いないと仮定しています。

これをひっくり返して、幸せな人をhappy/1事実で明示的に定義し、幸せsad/1でない人を定義して、悲しいことがなければ幸せに違いないと仮定することができます。

sad(X) :-
    person(X),
    \+ sad(X).

and述語は引き続き適用されますhappy_all/1sad_all/1

happy/1事実をと と混ぜ合わせたい場合sad/1、これは一貫性の問題を引き起こす可能性があります: (1) 人が幸せまたは悲しいと定義されていない場合... では、彼らは何ですか? (2) 人が幸せで悲しいと定義されている場合はどうなりますか?

意味的には、誰かが幸せでも悲しんでもいないことを許可する場合sad/1は、 と の両方をhappy/1明示的に定義することをお勧めします。あなたはこれを行うことができます:

person(bob).
person(tim).
person(steve).
person(roy).
person(jack).

sad(bob).
sad(tim).

happy(steve).
happy(roy).

happy_all(A) :-
    findall(X, happy(X), A).

sad_all(A) :-
    findall(X, sad(X), A).

ただし、述語は既に事実であるため、述語を定義しないでください。それは物事をシンプルに保ちます。幸せなのか悲しいのかわかりません。happy/1sad/1jack

しかし、人が幸せでも悲しくもない場合は、幸せで、そのルールを元に戻す必要があると言いたい場合はどうでしょう。あなたが言及したループを避けるために、ルール名とファクト名を混在させません。その場合:

person(bob).
person(tim).
person(steve).
person(roy).
person(jack).

sad(bob).
sad(tim).

happy(steve).
happy(roy).

% A person is happy if they are, in fact, happy
happy_person(X) :-
    happy(X),
% A person is happy if they are neither happy or sad
happy_person(X) :-
    person(X),
    \+ happy(X),
    \+ sad(X).

% A person is sad if they are, in fact, sad
sad_person(X) :-
    sad(X).

% Who are all the happy people?
happy_all(A) :-
    findall(X, happy_person(X), A).

% Who are all the sad people?
sad_all(A) :-
    findall(X, sad_person(X), A).
于 2015-12-01T21:34:06.957 に答える