コンテキスト

以下の関数はすべてのCSint型変数に発生したイベントについての情報を保持している ヒープ領域にアクセスするためのものです。 ここでいうイベントとは、制約伝播により引き起こされるCSint型変数の領域の変化 (known, newMin. newMax, neq) であるか、制約の設定を指します。.

cs_search()のような木探索のための組み込み関数を使用する場合には、 以下の関数を利用することはありませんが、探索のための関数を自分で作成するような場合には、 以下の関数を利用してバックトラックの制御を行うことができます。

int cs_saveContext()

コンテキストを保存します。これにより、保存した時点のすべてのCSint 型変数の状態および制約の状態に戻ることが できるようになります。

この関数が返す整数は label として、cs_forgetSaveContextUntil(), cs_acceptContextUntil() あるいは cs_restoreContextUntil() を呼び出す時に引数として渡す必要があります。

void cs_forgetSaveContext()

直前の cs_saveContext() の呼び出しをキャンセルします。 cs_event()関数中では、cs_acceptContext() ではなく、 本関数を使わなくてはなりません。

void cs_restoreAndSaveContext()

コンテキストを直前の cs_saveContext() 呼び出し以前と同じ状態に戻し、再び cs_saveContext() を呼び出します。

void cs_acceptContext()

直前の cs_saveContext() 呼び出し以降にCSint型変数に発生したのすべての変化を受け入れます (コンテキストはもう元には戻せなくなります)。

この関数は直前の cs_saveContext() 呼び出し以降にヒープ領域に確保されたメモリを解放します。

直前の cs_saveContext() 呼び出し時点へのバックトラックができなくなってしまいますので cs_acceptContext() は cs_event() 関数中で呼び出していけません。

void cs_acceptAll()

最初の cs_saveContext() 呼び出し以降にCSint型変数に発生したのすべての変化を受け入れます。 この関数はヒープ領域に確保されたすべてのメモリを解放します。

void cs_restoreContext()

コンテキストを直前の cs_saveContext() 呼び出し以前と同じ状態に戻します。

void cs_restoreAll()

コンテキストを最初の cs_saveContext() 呼び出し以前と同じ状態に戻します。

以下の3つの関数は引数として int型のラベルをとります。このラベルは事前に呼び出された cs_saveContext() が返したものでなくてはなりません。

void cs_forgetSaveContextUntil(int label)

label によって参照される状態までのすべての cs_saveContext() 呼び出しを無効にします。

void cs_acceptContextUntil(int label)

label によって参照される cs_saveContext() 呼び出し以降にCSint型変数に発生したのすべての変化を受け入れます。 (受け入れたコンテキストはもう元に戻せなくなります。)

この関数はlabel によって参照される cs_saveContext() 呼び出し以降にヒープ領域に確保されたメモリを解放します。

void cs_restoreContextUntil(int label)

コンテキストは label により参照される cs_saveContext() の呼び出しより前の状態に戻されます。

例:cs_search()の手続きは、以下のように実装することができます。:

IZBOOL cs_search(CSint **allvars, int nbVars, CSint* (*findFreeVar)(CSint **allvars, int nbVars)) {
  CSint *var = findFreeVar(allvars, nbVars);
  if (var) {
    int val;
    cs_saveContext();

    for (val = cs_getMin(var); val <= cs_getMax(var); val = cs_getNextValue(var, val)) {
      if (cs_EQ(var, val) && cs_search(allvars, nbVars, findFreeVar))
        return TRUE;

      cs_restoreAndSaveContext();
    }

    cs_acceptContext();
    return FALSE;
  }
  else {
    return TRUE;
  }
}