在SICStus Prolog中使用索引词评估表达式

时间:2018-07-11 07:26:58

标签: prolog clpfd

我正在尝试在SICStus Prolog中编写谓词,以便给定表达式,我可以对其进行评估(可能多次)。预期效果如下:

def go(value):

更详细的代码也是如此:

?- A is 1, H = A+2+2, C is H.
C = 5 ?
yes

现在,如果A代替索引,例如在1..3中说A,那么它将不再起作用。关于如何解决它的任何想法?

较长的代码应按以下方式使用:

testing(Variables, Updates, Values, Result):-
    assert(temp(Variables, Updates)),
    temp(Values, Result),
    abolish(temp/2).

evaluate([],[]).
evaluate([Term|T1],[H|T2]):-
    H is Term,
    evaluate(T1,T2).

但是与小示例一样存在同样的问题:我不能以这种方式提供值范围:

?- testing([A,B,C], [A+1,B+C,max(A,B)], [0,0,0], Result), evaluate(Result, R).
Result = [0+1,0+0,max(0,0)],
R = [1,0,0] ? 
yes

有什么建议吗?

3 个答案:

答案 0 :(得分:1)

我当前的解决方案要求将is / 2替换为val_of / 2。它可行,但是我仍然相信应该有一个更好/更快的实现。

testing(Variables, Updates, Values, Result):-
    assert(temp(Variables, Updates)),
    temp(Values, Result),
    abolish(temp/2).

evaluate([],[]).

evaluate([Term|T1],[H|T2]):-
    val_of(H,Term),
    evaluate(T1,T2).


val_of(E,E):- number(E),!.
val_of(E,E):- var(E),!.
val_of(V,E1+E2):- !, val_of(V1,E1), val_of(V2,E2), V #= V1+V2.
val_of(V,E1-E2):- !, val_of(V1,E1), val_of(V2,E2), V #= V1-V2.
val_of(V,max(E1,E2)):- !, val_of(V1,E1), val_of(V2,E2), V #= max(V1,V2).
val_of(V,min(E1,E2)):- !, val_of(V1,E1), val_of(V2,E2), V #= min(V1,V2).
val_of(V,abs(E1,E2)):- !, val_of(V1,E1), val_of(V2,E2), V #= abs(V1,V2).

一个测试示例:

| ?- X in 1..3, testing([A,B], [A+1,B], [X,0], R), evaluate(R,R1).
R = [X+1,0],
R1 = [_A,0],
X in 1..3,
_A in 2..4 ? 
yes

答案 1 :(得分:1)

我认为您只需要

evaluate([],[]).
evaluate([Term|T1],[H|T2]):-
    H #= Term,
    evaluate(T1,T2).

但是temp / 2关系不是必需的,因此真正的简化可能是:

testing(Variables, Updates, Values, Result):-
  maplist(#=, Updates, Values), Result=Variables.

产生

?- testing([A,B,C], [A+1,B+C,max(A,B)], [0,0,0], Result).
A = -1,
B = C, C = 0,
Result = [-1, 0, 0].

(注意:?- [library(clpfd)].之后在SWI-Prolog中测试)

答案 2 :(得分:1)

我的最终解决方案是基于@CapelliC和@false提供的有用答案和注释对原始代码进行修改的版本:

sets <- lapply(seq(-97, 99, by = 2), function(x) {
    nums[1] = x
    print(nums)
})
for(i in 1:99) {
  x1value = sets[i[1]]
  mean = mean(sets[i])
  median = median(sets[i])
}

我原始代码中的主要问题是评估/ 2中缺少呼叫/ 1。

SICStus Prolog中的一个测试示例如下:

testing(Variables, Updates, Values, Result):-
    copy_term(Variables-Updates, Values-Result).

evaluate([],[]).
evaluate([Term|T1],[H|T2]):-
    call(H #= Term),
    evaluate(T1,T2).