变量未声明

Variable undeclared

我有一个函数,它从列表中获取第一个项目,并检查该项目是否是多个项目中的一个,相应地执行一些函数并递归地执行列表中的下一个项目。

我的问题是在第 6 行中,实例化为列表第一项的变量不再定义,我无法弄清楚为什么。

我刚开始使用 KBS,如果我的语言不正确,请原谅我。

1 f(L) :- 
2     [F|Ls] = L,
3     (
4        (F = value1 -> ...);
5        (F = value2 -> ...)
6    ) -> f(Ls); format('~w is not a valid action', [F]).

->/2 用法示例:

do_something_with_first_elem([Head|_]) :-
    do_something_with_elem(Head).
    
do_something_with_elem(Elem) :-
    ( Elem = a -> writeln('Head is a')
    ; Elem = b -> writeln('Head is b')
    ; Elem = 3 -> writeln('Head is 3 (a number)')
    ; format('~w is not a valid action', [Elem])
    ).

结果swi-prolog:

?- do_something_with_first_elem([b, c, d]).
Head is b
true.

?- do_something_with_first_elem([z, c, d]).
z is not a valid action
true.

编译代码后,提出以下问题:

?- listing(f).

f(L) :-
    (   L=[F|Ls],                              % <== unification IS PART OF the condition!
        (   F=value1
        ->  ...
        ;   F=value2
        ->  ...
        )
    ->  f(Ls)
    ;   format('~w is not a valid action', [F]) % <== when condition fails, unification is UNDONE
    ).

如您所见,统一是条件的一部分。因此,当条件失败时,统一为未完成,转F一个变量.

解决问题,格式化代码如下:

f(L) :-
     [F|Ls] = L,                  % <== Now, unification IS NOT PART OF the condition!
     (   (   (F = value1 -> ...)
         ;   (F = value2 -> ...) )
     ->  f(Ls)
     ;   format('~w is not a valid action', [F]) ).