我有这样的功能:
myFunction(V1, V2, Result) :-
Result is V1/V1cover + V2/V2cover,
write(Result).
myFunction(0,0,0).
keepValue(V1,V2,V1cover,V2cover) :-
V1cover is V1,
V2cover is V2.
还有其他函数多次调用myFunction并返回结果。但是,我想得到第一个结果,即第一次调用myFunction并保持它以后用于调用(在这种情况下,它是V1cover和V2cover)。例如,第一次调用myFunction(4,4,A)。然后它返回A = 2.之后我想保持V1cover(4)和V2cover(4)的值用于下一个被叫时间。我怎么能这样做?我尝试应用缓存的技术,并将其应用到myFunction:
:- dynamic(cachedGoal_sol/2).
reset :-
retractall(cachedGoal_sol(_, _)).
eq(A, B) :-
subsumes_term(A, B),
subsumes_term(B, A).
cached_call(Goal) :-
\+ (cachedGoal_sol(First,_), eq(First, Goal)),
copy_term(Goal, First),
catch(
( Goal,
assertz(cachedGoal_sol(First, Goal)),
fail
),
Pat,
(reset, throw(Pat))).
cached_call(Goal) :-
cachedGoal_sol(First, Results),
eq(First, Goal),
Results = Goal.
myFunction(V1, V2, Result) :-
**cached_call(keepValue(V1,V2,V1cover,V2cover),**
Result is V1/V1cover + V2/V2cover,
write(Result).
但它不起作用,当我尝试第二次运行myFunction(2,3,A)并跟踪程序时,它实际上存储了第一个调用的解决方案,但我无法获得V1cover,V2cover的第一个值,因为第二个cached_call()中的eq()失败。有没有办法只获得V1cover,V2cover的值而不接触V1,V2,因为它们是输入的?非常感谢您的回答。
答案 0 :(得分:2)
您的代码有一些错误,而且有点太复杂了。我会尝试给你一个可能对其他人有用的答案。
假设我们需要一个谓词来存储有关首次满足目标的上下文的信息。
我将使用一个简单的例子。让我们说我们有一条规则可以找到1到4之间的数字对,加上6。
sum_to_six(X, Y) :- between(1, 4, X), between(1, 4, Y), X + Y =:= 6.
试图找到满足上述规则的所有对,得到以下答案:
?- findall(pair(X,Y), sum_to_six(X, Y), All).
All = [pair(2, 4), pair(3, 3), pair(4, 2)].
现在,让我们回到你的问题。让我们假设我们需要满足目标的第一对。我们应该修改谓词sum_to_six/2
的规则。
sum_to_six(X, Y):-
between(1, 4, X), between(1, 4, Y), X + Y =:= 6,
store_first(pair(X,Y)).
子目标store_first(pair(X,Y))
每次都成功,但是第一次断言pair(X,Y)
(如果动态内存中没有其他pair(_,_)
)。所以,你需要的答案可能与此类似:
store_first(Goal):-
Goal =.. [Name | Args], %% Name is the name of the predicate
length(Args, N), %% N represents its arity
length(NVars, N),
Test =.. [Name | NVars], %% Test is a goal like p(_, _, _, ...)
(
Test, !
;
assertz(Goal)
).
现在,要获取存储的信息:
?- retractall(pair(_,_)), findall(_, sum_to_six(_,_), _), pair(FirstX, FirstY).
FirstX = 2,
FirstY = 4.
答案 1 :(得分:1)