PrologでModuleの取り扱い(1)

PrologでModuleを使っていると、Namespaceの扱いがやや面倒になります。たとえば、「data/2」というファクトを処理する述語「process_data/1」というのを、「process」と云うModuleで定義したとします。

:-module(process,[process_data/1]).
process(DataName):-
  data(DataName,Data),
  writeln(Data),
  true.

こういったModuleは他のファイルから大抵Includeされて使用されます。こんな感じで。

:-use_module(process).
data(room01,hanako).
data(room02,tarou).

test:-
  process_data(X),
  fail.

dataをすべて表示する「つもりの」プログラムですが、これはうまくいきません。なぜなら、Module:processのprocess_dataが扱うdataのNamespaceはprocessだからです。

つまり、

  • process:data
  • user:data

は違うということ。

そこで、SWI-prologには「multifile」という命令があります。これは、「multifile で指定された述語は他のNamespaceでも使用されている」と指定する命令です。

:-module(process,[process_data/1]).
:-multifile data/2.
process(DataName):-
  data(DataName,Data),
  writeln(Data),
  true.

したがって、こうしておけば、Moduleからもuser空間の述語名を使用できるようになります。