如何用字符串值求值变量?

时间:2019-04-07 01:00:08

标签: prolog

我的代码非常适合数字,但单引号错误。我正在尝试编写一个foldl函数。当我做foldl1(concat, ['a','b'], X)时,它报告类似"ERROR: Arithmetic: 'ab/0' is not a function".的问题是什么? Prolog不允许将is与字符串一起使用?

foldl1(P, [H], X) :-
    X is H.

foldl1(P, [H|T], X) :-
    foldl1(P, T, Y),
    call(P, H, Y, Z),
    X is Z.

2 个答案:

答案 0 :(得分:2)

is / 2在右边计算算术表达式,在结果与左边的项统一。还针对 head '参数执行统一,因此您可以编写简化的foldl1 / 3像

foldl1(_, [H], H).
foldl1(P, [H|T], Z) :-
    foldl1(P, T, Y),
    call(P, H, Y, Z).

测试:

?- foldl1(plus,[1,2,3],R).
R = 6 ;
false.

?- foldl1(concat,[1,2,3],R).
R = '123' ;
false.

由于[H][H|T]T=[]重叠的地方,我会在递归基数之后放置一个切口,以避免在最终回溯时(例如,重做由我引起,在解释器等待我的选择时,在预期的第一个答案后输入;。 切割后(希望您可以轻松地发现它的放置位置),我们得到:

?- foldl1(plus,[1,2,3],R).
R = 6.

?- foldl1(concat,[1,2,3],R).
R = '123'.

现在,口译员“知道”在第一个……之后没有更多答案了。

答案 1 :(得分:1)

也有可能使用第一参数索引来实现foldl1/3谓词,以避免不切分的虚假选择点,并且这也是尾递归的。从Logtalk库meta对象中:

:- meta_predicate(foldl1(3, *, *)).
foldl1(Closure, [Head| Tail], Result) :-
    fold_left_(Tail, Closure, Head, Result).

fold_left_([], _, Result, Result).
fold_left_([Arg| Args], Closure, Acc, Result) :-
    call(Closure, Acc, Arg, Acc2),
    fold_left_(Args, Closure, Acc2, Result).

通话示例:

?- meta::foldl1(plus,[1,2,3],R).
R = 6.

?- meta::foldl1(concat,[1,2,3],R).
R = '123'.