如何使用Prolog检查某个strA是strB的子串?

时间:2014-03-26 19:45:55

标签: prolog

所以基本上我使用这段代码来检查子字符串:

substring(X,S) :- append(_,T,S), append(X,_,T), X \= [].

我的意见是:

substring("cmp", Ins)   % Ins is "cmp(eax, 4)"

但是当我使用swi-prolog来跟踪这段代码时,我发现了这个:

substring([99, 109, 112], cmp(eax, 4))

显然它失败了......

那么有人可以给我一些帮助吗?

2 个答案:

答案 0 :(得分:0)

SWI-Prolog将recently changed传统的字符串文字作为'代码列表'更高效的内存表示(从版本7开始)。

因此(其中更难以解释),追加/ 3不再适用于您的任务,除非您明确转换为代码列表。

在上下文中,已经引入了许多内置函数,例如sub_string / 5:例如,尝试

?- sub_string("cmp(eax, 4)", Start,Len,Stop, "eax").
Start = Stop, Stop = 4,
Len = 3

答案 1 :(得分:0)

将此字符串设为cmp(eax, 4)形式的字词。在这里,在Prolog术语中,你有:

  • 术语cmp(eax, 4)
  • 使用仿函数cmp/2
  • 第一个参数是原子eax
  • 和第二个参数整数4

现在您有了一个术语,您可以在谓词(统一)的头部使用模式匹配来编写谓词,如:

apply_instruction(cmp(Reg, Operand) /*, other arguments as needed */) :-
    /* do the comparison of the contents of _Reg_ and the values in _Operand_ */
apply_instruction(add(Reg, Addend) /*, other arguments */) :-
    /* add _Addend_ to _Reg_ */
% and so on

如何从输入中创建一个术语:有很多方法,最简单的方法是读取一整行(取决于您正在使用的Prolog实现,在SWI-Prolog中,假设您的输入流在< EM>在):

read_line_to_codes(In, Line).

然后使用DCG解析它。 DCG看起来可能像:

instruction(cmp(Op1, Op2)) -->
    "cmp",
    ops(Op1, Op2).

instruction(add(Op1, Op2) -->
    "add",
    ops(Op1, Op2).

ops(Op1, Op2) -->
    space,
    op1(Op1), optional_space,
    ",", optional_space,
    op2(Op2),
    space_to_eol.

% and so on

然后,您可以使用phrase/2将DCG应用到您已读过的行:

phrase(instruction(Instr), Line).