1. 序章

述語は、答えが真か偽か、言い換えれば「はい」か「いいえ」かを質問します。

コンピュータサイエンスと数学では、この質問は関数の形で出てきます。 関数の結果はtrueまたはfalse(yesまたはno)です。 答えのデータ型は、数学とコンピュータサイエンスの両方で、booleanと呼ばれます。

このチュートリアルでは、いくつかの例を使用して、これらの概念についてもう少し詳しく説明します。

2. 簡単な定義

述語は、ブール値を回答として返す一連のパラメーターの関数です

boolean predicate(set of parameters)

boolean の値は、trueまたはfalse(yesまたはno)のいずれかです。 関数への入力は、必要なパラメーターの任意のセットにすることができます。

たとえば、「気温は25を超えていますか」などの数値の質問がある場合、次のように書くことができます。

temperature > 25

答えは、たとえば温度が30の場合はtrue、温度が20の場合はfalseのいずれかです。

この述語をJavaの関数として記述する場合、次のように書くことができます。

boolean checkTemperature(int temperature) {
    return temperature > 25;
}

3. ブール値とブール式

すべてのプログラミング言語にはブールデータ型があり、それぞれにtrue、false、および一連のブール演算を表現する方法があります。

この表にいくつかの例を見ることができます。

言語 データ・タイプ 真実 間違い サンプル式
C、C ++、C#
bool
true
false
x>2 && y==5
Java
boolean
true
false
x>2 && y==5
Java(クラスとして)
Boolean
TRUE
FALSE
x>2 && y==5
Python <class 'bool'>
True
False
(x>2) and (y==5)
Fortran
logical
.true.
.false.
(x.GT.2).AND.(y.EQ.5)
アルゴル
BOOLEAN
TRUE
FALSE
X GTR 2 AND Y EQL 5

3.1. 明示的なブール値はありません

Perl、Tcl、LISP、SQLなどの一部の言語には、明示的なブールデータ型がありません。 これらの言語は、明示的には述べられていませんが、ブールデータ型の基礎として整数、バイト、またはビットを使用します。 基本的に、ゼロは偽であり、他のすべては真です。

たとえば、C言語では、boolデータ型は_BOOLデータ型から取得されます。 bool の使用は、よりユーザーフレンドリーであると考えられていました。

_BOOL データ型は、 unsignedintに基づいています。 次のコードのように、Xをデータ型_BOOLに割り当てるとします。

_BOOL X;
X = 0      /* X gets assigned 0 */
X = 1      /* X gets assigned 1 */
X = 5      /* X gets assigned 1 */
X = "Hi"   /* X gets assigned 1 */

ここで、 X は、ゼロ以外が割り当てられたときに1の値を想定していることがわかります。

4. プログラミングの述語

4.1. 命令型プログラムのフロー制御

プログラミングで決定を下さなければならないときはいつでも、述語が必要です。

C、Java、Python、Fortranなどの一般的なプログラミング言語などの必須プログラミング言語では、一般的な決定ステートメントはIFステートメントです。[X198X ] 一連の条件が真の場合、何かを実行します。 それ以外の場合は、他のことを行います。

たとえば、Javaでは次のように書くことができます。

if (x > 25) {
    /* true: do something */
} else {
    /* false: do something else */
}

x>25が述語です。 これは数値パラメーターxの関数であり、ブール、つまりtrueまたはfalseを答えとして与えます。

関数として記述すると、(このJavaの例のように)次のように言うことができます。

boolean checkX(int x) {
    return x > 25;
}

4.2. フィルタとしての述語

述語は、オブジェクトのフィルターと見なすことができます。 述語を使用すると、述語を満たさないオブジェクトのセットを除外できます。

たとえば、 objectsという名前のオブジェクトのセットがあり、フィルタリングしたいとします。 フィルタ基準は、関数の本体である predicate(object)です。 predicate(object)がtrueの場合、オブジェクトをfilteredsetに配置します。 それ以外の場合は無視します。

擬似コードは次のようになります。

ただし、述語は必ずしも数字を使用する必要はありません。 たとえば、一連の動物をフィルタリングできます。

lion, elephant, parrot, whale, horse, eagle, cat, dog, human, robin, squirrel

鳥のセットを作成する場合は、述語を使用します。

isABird(animal) := true if animal is a bird

最終的なセットは次のようになります。

parrot,eagle,robin

これを実際にどのようにプログラムするかは、動物の表現によって異なります。

たとえば、各動物を行列 AnimalDescription。のdouble値のセットとして表すことができます。各行は異なる動物であり、各列は動物の特定のプロパティです。

  • 0: IDOfAnimal
  • 1: TypicalHeight (メートル単位)
  • 2: TypicalWeight (グラム)
  • 3: TypicalSpeed (メートル/秒)
  • 4: HasFeathers、いいえの場合は0.0、はいの場合は1.0
  • 5: CanFly、いいえの場合は0.0、はいの場合は1.0
  • 6: NumberOfLegs
  • 7: LaysEggs、いいえの場合は0.0、はいの場合は1.0

次に、鳥を次のように識別するための述語を作成します。

AnimalDescription(animal, 4) == 1

もちろん、生物学者の友人にこれで十分かどうか尋ねます。

4.3. ソートアルゴリズムの述語

並べ替えアルゴリズムの鍵は、2つのオブジェクト間の関係を決定することです。 並べ替えの方法に関係なく、すべてのアルゴリズムがオブジェクト間の関係を決定する必要があることがわかります。 この関係を与えるのは述語の役割です。

多くの場合、一方のオブジェクトがもう一方のオブジェクト「より大きい」であるかどうかを判断する必要があります。

isGreaterThan(object1,object2) := true if object1 is greater than object2

「より大きい」の定義は、オブジェクトとそれらの表示方法によって異なります。

たとえば、動物を使った前の例では、次のように定義できます。

isGreaterThan(animal1,animal2) := true if animal1 weighs more than animal2

これにより、最大体重から最小体重までの動物のリストが得られます。

しかし、動物を小さいものから大きいものへとリストしたい場合はどうでしょうか。 これは、次の方法で簡単に実行できます。

isGreaterThan(animal1,animal2) := true if animal weighs less than animal2

つまり、アルゴリズムに「isGreaterThan」述語が必要な場合でも、「より大きい」[の代わりに「より小さい」を使用しても、この述語を任意の方法で定義できます。 X189X]。 前に示した表現例では、述語は次のようになります。

isGreaterThan(animal1,animal2) := AnimalDescription(animal1, 2) < AnimalDescription(animal2, 2)

4.4. 並べ替えとフィルタリングにおけるオブジェクト指向述語

オブジェクト指向プログラミングでは、述語を、必要な関数を定義するクラスにカプセル化できます(例:“ isGreaterThan” )。 並べ替えまたはフィルタリングのアルゴリズムには、処理するオブジェクトのセットだけでなく、述語を持つクラスも含まれます。

Javaでは、最初に次の関数を使用して抽象クラスを定義します。

class Predicate {
    abstract boolean isGreaterThan(Object x1, Object x2);
}

次に、並べ替えまたはフィルタリングアルゴリズムは、定義でこの抽象クラスを使用して機能を実行します。 彼らは、isGreaterThan関数が定義されているクラスを期待します。

たとえば、FilterObjectsクラスを定義できます。このクラスにはaddToFilteredSetという関数があり、フィルター処理されたオブジェクトをfilteredsetに追加します。

class FilterObjects {
    void addToFilteredSet(Set setOfObjects, 
      Set filteredSet, 
      Predicate predicate) {
        for(Object object: setOfObjects) {
            if(predicate.isGreaterThan(object)) {
                filteredSet.add(object);
            }
        }
    }
}

5. ファジー論理述語

はい/いいえの質問をするとき、答えは実際には真ではないまたは偽である場合があります。

わからないか、その中間にあるのかもしれません。 たとえば、質問をしたり、温度を使用して質問に答える述語を設定したりすると、次のようになります。

質問:水は熱いですか?

述語: IsItHot(T)

水が沸騰していて、温度 T が摂氏100度の場合、答えは間違いなく「はい」です。 さらに、水がほぼ氷点下になっている場合、たとえば摂氏5度の場合、答えは間違いなく「いいえ」です。

しかし、水を沸騰させてから、雪の中で外で冷やすとどうなりますか? まず、水は熱く、述語への答えは真実です。 しかし、1時間後、水は間違いなく冷たくなり、述語に対する答えは誤りです。

しかし、述語への答えはどの温度で真から偽になりましたか? 40でしたか? 30? 25? たとえば、31度で水が熱くなり、30度で突然水が冷たくなると思いますか? 私たちは、水が冷えて、しばらくの間ぬるま湯になり、その後冷えることを知っています。 基本的に、「どちらかわからない」という領域があります。

さらに複雑なことに、ノルウェーのSvenは、イタリアのGiovanniとは「暑い」という印象が異なる可能性があります。

ここでファジーロジックが役立ちます。 これは、trueとfalseの間の段階的な移行を提供します。

5.1. ファジー論理述語の例

この図では、「暑いですか?」という質問に答える述語 IsItHot(T)を定義しています。 ここで、 IsItHot(T)= 1.0 の場合、答えは「はい」であり、 PIsItHot(T)= 0.0 の場合、答えは「いいえ」です。

通常のブール(true / false)ロジックでは、ホットとコールドの間に急激な遷移があることがわかります。 これは私たちの直感に対応していません。 ただし、ファジー論理述語では、ホットとコールドの間の遷移が遅くなります。 答えが1.0に近いほど、水は熱くなり、0.0に近いほど、水は冷たくなります。 値が0.5の場合、実際にはわかりません。

6. 最後の言葉

このチュートリアルでは、結果としてブール値を返す関数としての述語の定義を見てきました。

さらに、プログラムフロー、フィルタリング、および並べ替えでの述語の概念のいくつかの使用法を見ました。 つまり、質問をしたり、決定を下したりするときはいつでも、述語の概念が機能します。

また、ブール概念をファジー論理に拡張することも検討しました。 これは、私たちが白黒の決定を下すことができない場合があることを私たちが認識するところです。 時々灰色の領域があります。