我需要编写一个自定义函数,该函数将被其他固定函数多次调用。在此函数中,在第一个调用时,它将返回文件的总行数。此函数的第二个调用时间forward,将返回此文件的小部分中的行数。我的问题是如何保留第一个返回的结果(文件的总行数)并将其用于我的函数的下一个调用时间。我只需要在这个函数中编写或声明任何东西(不在调用者中)。像这样:
myFunction(Input, MyResult, FirstResult) :-
calculateInputFunction(Input, Result),
!,
MyResult is Result,
... .
问题是,每次调用myFunction时,它都会收到不同的Input并返回不同的MyResult。但我想保留第一个MyResult用于myFunction的下一个调用时间。我怎样才能做到这一点?非常感谢你的回答。
myFunction([V1,V2], Result) :-
reset,
cached_all(a(V1,V2)),
use V1, V2 to calculate Result,
...
reset,
finishedCode.
以上是我的功能,还有其他函数通过将V1,V2的值传递给该函数并返回Result来调用myFunction。
答案 0 :(得分:2)
您需要的是某种形式的缓存机制。这必须以某种方式使用一些全球资源。动态数据库通常用于此目的 目的。这是一个非常简单的形式。在该领域中更为复杂的技术在表格的概念下是已知的。
:- dynamic(cachedgoal_sol/2).
reset :-
retractall(cachedgoal_sol(_,_)).
eq(A, B) :-
subsumes_term(A, B),
subsumes_term(B, A).
cached_call(Goal) :-
\+ ( cachedgoal_sol(Skel,_), eq(Skel, Goal) ), % No fitting Goal was cached
copy_term(Goal, Skel),
catch(
( Goal,
assertz(cachedgoal_sol(Skel,Goal)),
fail
),
Pat,
(reset, throw(Pat))).
cached_call(Goal) :-
cachedgoal_sol(Skel,XGoal),
eq(Skel, Goal),
XGoal = Goal.
用法:从reset.
开始,然后将Goal
换行为cached_call(Goal)
。当事情发生变化时,不要忘记重置!
以下是一些解释:
reset/0
只删除所有缓存的结果。
eq/2
等于重命名变量,只要两个参数的变量集是不相交的。
cachedgoal_sol/2
是一个动态谓词。它用于存储特定目标的解决方案(实际上:答案)。为此,它在第一个参数中保留实际目标的副本,在第二个参数中保留实际答案/解决方案。请注意,对于一个谓词,可能存在多个不同的查询。说:member(X,[a,b,c])
和member(X,[X1,X2,X3])
。这些查询将彼此独立地处理和缓存。
如果必须重新缓存目标,则会创建该术语的副本以具有"密钥"用于缓存。然后,执行目标并存储每个答案 - 这是彻底完成的。对于有多个答案的查询,这尤其有用。
此外,目标受catch/3
捕获所有错误Pat
的保护。以这种方式,在执行目标时发生的所有错误都将导致reset
缓存。这对于非终止查询尤为重要:cached_call(length(L,N))
否则会在缓存中留下有限数量的解决方案 - 这会使缓存处于不一致状态......
在任何情况下,第一个句子总是失败。所以这只是为了更新缓存的副作用。
第二个子句现在使用缓存。请注意,XGoal = Goal
"在左侧"后面是不可能的,因为eq/2
必须确保我们仅使用同一查询的结果。
正如我已经说过的:这是一种非常天真的方式,但至少它很简单且相对健壮。
关于你原来的节目。你现在可以写:
..., cached_call(calculateInputFunction(Input, Result)), ...
每当你需要这个价值时。