首页 > 解决方案 > 序言。为变量赋值后,程序输出从 `yes` 变为 `no`

问题描述

我有一个简单的任务是在另一个数组中查找数组的位置。顺便说一句,我正在使用GNU Prolog 1.4.5.

parse([], _) :- true. %parsed sub means that we found it
parse([SHead|STail], [Head|Tail]) :-
    write(SHead), write(' '), write(STail), write(' | '), write(Head), write(' '), write(Tail), nl,
    (
        SHead =:= Head -> 
            parse(STail, Tail) 
        ;
            false
    )
.

findsub([_|_], [], _) :- false. %unparsed sub & empty string means there is no sub
findsub([SHead|STail], [Head|Tail], Pos) :-
    (
        var(Pos) -> Pos = 0 ; true %first-time init
    ),
    XPos is Pos + 1,
    (
        SHead =:= Head ->
            (
                parse(STail, Tail) ->
                    true %subarray found
                ;
                    findsub([SHead|STail], Tail, XPos) %continue to next el
            )
        ;
            findsub([SHead|STail], Tail, XPos)
    )
.

程序正常工作,但我找不到正确设置Pos变量值的方法,因此它会返回实际位置。添加Pos is XPos,parse(STail, Tail) ->,改变程序行为不正确。不明白为什么。测试数据:findsub("a", "sdfsfgasfdsfsdf", Pos).

标签: prologlogic

解决方案


请注意,在 Prolog 中没有赋值操作(如在过程语言中)。=/0运算符用于术语统一

查看您的代码,我们可以从简化parse/2谓词开始:

parse([], _). %parsed sub means that we found it
parse([SHead|STail], [Head|Tail]) :-
    write(SHead), write(' '), write(STail), write(' | '),
    write(Head), write(' '), write(Tail), nl,
    SHead =:= Head, 
    parse(STail, Tail).

对于您的findsub/3谓词,您将需要使用一个累加器,即一个辅助参数来携带当前位置,在进行递归调用时将其递增:

findsub(SList, List, Position) :-
    findsub(SList, List, 1, Position).

findsub([_|_], [], _, _) :-
    % unparsed sub & empty string means there is no sub
    false.
findsub([SHead|STail], [Head|Tail], Position0, Position) :-
    (   SHead =:= Head ->
        (   parse(STail, Tail) ->
            % subarray found
            Position = Position0
        ;   % continue to next element
            Position1 is Position0 + 1,
            findsub([SHead|STail], Tail, Position1, Position)
        )
    ;   Position1 is Position0 + 1,
        findsub([SHead|STail], Tail, Position1, Position)
    ).

您的示例电话:

| ?- findsub("a", "sdfsfgasfdsfsdf", Pos).

Pos = 7
yes

推荐阅读