述語に対し、適用される環境(引数列)を持っているのがゴールレコードである。 KLICではゴールレコードは、(通常のKL1データを置くのと同じ)ヒープ領域に 置かれており、GCの対象になる(回収はGCによってのみ行われる)。
この構造はinclude/klic/struct.h 内の、goalrec 構造により
定義されている。
struct goalrec {
struct goalrec *next; 次のゴールを指すためのリンク領域
Const struct predicate *pred; 述語記述子へのポインタ
q args[6]; 引数領域。
};
ゴールスタックは上記構造の線型リストにより表現される。 線型リストにせずにスタック状にゴールレコードを隣接して 置くことは可能ではあるが、優先度別に複数のゴールスタックを管理する必要があり、 各々を個別にメモリ管理することは繁雑であるということ、 KL1では中断処理があるため、 必ずしもゴール生成順と消滅順とは逆順(LIFOの関係)にならないことに起因している。
上記の定義からは明らかではないが、ゴールレコードは、不定長の構造であり、 引数の数に応じて末尾が伸縮する。つまり、args の領域は、predで示される 述語記述子内にある引数個数分だけ確保される。
このような実現をとらずに ゴールレコードを原則固定長メモリ塊の組合せにより表現し、 その固定長メモリ塊をヒープとは別にフリーリスト管理する、という実装も可能である (実際、初期のKLICではそのような実現をしていた)。 しかしながら、この方法は、ゴールを組合せる処理が繁雑になること、 純粋未定義変数をゴールレコード中に置くことが難しくなり、 純粋未定義変数をゴールレコードに置かないよう工夫をすることが繁雑になること などの理由により、現在の方式に改められた。
結果的に、ゴールレコードをヒープに置くことにより、 不定長の構造の管理が大きく簡略化され、また、 純粋未定義変数は直接ゴールレコード内に置いても何の配慮もいらなくなった。
このゴールレコードは以下の2つの状態を持つ。
これらの状態にあるゴールについて以下に記述する。