Flowmode 声明

在 Prolog 中编程时,并不总是可能或者希望创建为每个可能的参数组合统一的谓词。例如,谓词 between(X,Y,Z) 表示 Z 在数字上位于 X 和 Y 之间。在 X,Y 和 Z 全部绑定的情况下(Z 在 X 和 Y 之间或者不是),或者在哪里,很容易实现谓词 between(X,Y,Z)。X 和 Y 是绑定的,Z 是自由的(Z 与 X 和 Y 之间的所有数字统一,或者如果 Y <X 则谓词失败); 但在其他情况下,例如 X 和 Z 被绑定而 Y 是自由的,可能存在无限数量的统一。虽然这可以实现,但通常不会。

流声明模式声明允许显式描述谓词在使用绑定参数的不同组合调用时的行为方式。在 between 的情况下,声明将是:

%! between(+X,+Y,+Z) is semidet.
%! between(+X,+Y,-Z) is nondet. 

每行指定谓词的一个潜在调用模式。每个参数都用+来装饰,以指示它被绑定的情况,或者 - 来指示它不存在的情况(还有其他装饰可用于更复杂的类型,例如可能部分绑定的元组或列表)。关键字 after 表示该情况下谓词的行为,可能是以下之一:

  • det 如果谓词总是成功而没有选择点。例如 add(+X,+Y,-Z)det,因为添加两个给定数字 X 和 Y 将始终只有一个答案。
  • semidet 如果谓词成功或失败,没有选择点。如上所述,between(+X,+Y,+Z)semidet,因为 Z 在 X 和 Y 之间或者不是。
  • multi 如果谓词总是成功,但可能有选择点(但也可能没有)。例如,factor(+X,-Y) 将是 multi,因为一个数字总是至少有一个因子 - 本身 - 但可能有更多。
  • nondet 如果谓词可能选择点成功,或者失败。例如,between(+X,+Y,-Z)nondet,因为在 X 和 Y 之间可能存在 Z 与数字的几种可能的统一,或者如果 Y <X 则它们之间没有数字并且谓词失败。

流/模式声明也可以与参数标签结合使用,以阐明术语的含义或键入内容。例如,between(+From:Int, +To:Int, +Mid:Int) is semidet

在纯 Prolog 中,流和模式声明是可选的,仅用于文档生成,但它们对于帮助程序员识别实例化错误的原因非常有用。

在 Mercury 中,流和模式声明(和类型)是必需的,并由编译器验证。使用的语法如上所述。

在 Visual Prolog 中,流和模式声明和类型也是必需的,语法也不同。上述声明将写成:

between : (int From, int To, int Mid) determ (i,i,i) nondeterm (i,i,o).

含义与上述相同,但区别在于:

  • 流/模式声明与类型声明分开(因为假设单个谓词的流/模式不会随类型重载而变化);
  • io 用于+-,并与基于排序的参数匹配;
  • 使用的术语不同。det 变成 proceduresemidet 变成 determnondet 变成 nondetermmulti 仍然是 multi)。