剪辑多个 EnvEval 查询会使先前的结果对象无效? [英] Clips multiple EnvEval queries invalidate previous result objects?

查看:52
本文介绍了剪辑多个 EnvEval 查询会使先前的结果对象无效?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我还有一个奇怪的问题,我已经解决了.但我不确定我只是幸运地修复了它,或者我真的明白发生了什么.所以基本上我已经通过以下方式对我的事实进行了查询:

I had a another strange problem that I solved already. But I'm not sure I just luckily fixed it or I really understand what's going on. So basically I have perform a query on my facts via:

DATA_OBJECT decay_tree_fact_list;
std::stringstream clips_query;
clips_query << "(find-all-facts ((?f DecayTree)) TRUE)";
EnvEval(clips_environment_, clips_query.str().c_str(), &decay_tree_fact_list);

然后我浏览事实列表并检索所需的信息.在那里,我还通过以下方式为上面找到的每个事实创建了另一个子查询"

Then I go through the list of facts and retrieve the needed information. There I also make another "subquery" for each of the found facts above in the following way

DATA_OBJECT spin_quantum_number_fact_list;
std::stringstream clips_query;
clips_query << "(find-fact ((?f SpinQuantumNumber)) (= ?f:unique_id "
  << spin_quantum_number_unique_id << "))";
EnvEval(clips_environment_, clips_query.str().c_str(),
  &spin_quantum_number_fact_list);

这对于第一个 DecayTree 事实来说一切正常,无论我从哪个位置开始,但对于下一个它会崩溃,因为事实地址是伪造的.我将问题追溯到我制作的子查询.所以我为解决这个问题所做的是将所有 DecayTree 事实地址保存在一个向量中,然后对其进行处理.由于到目前为止我找不到有关我的理论的任何信息,因此我想在这里提问.

This all works fine for the first DecayTree fact, no matter at which position I start, but for the next one it crashes, because the fact address is bogus. I traced the problem down to the subquery I make. So what I did to solve the problem was to save all the DecayTree fact addresses in a vector and then process that. Since I could not find any information about my theory so far I wanted to ask here.

所以我的问题很简单,就是:如果我执行两个查询,一个接一个地执行,在我调用第二个查询时,第一个查询的检索信息是否会失效?

So my question is quite simple, and would be: If I perform two queries, after each other, does the retrieved information of the first query get invalidated as soon as I call the second query?

推荐答案

EnvEval 函数应该在文档中标记为触发垃圾收集,但事实并非如此.CLIPS 在内部表示字符串、整数、浮点数和其他类似于其他语言(如 Java)的原语,这些语言允许类的实例,如字符串、整数和浮点数.由于这些值是动态创建的,因此在不再使用时需要进行垃圾回收.CLIPS 在内部使用引用计数来确定这些值是否被引用,但是当这些值返回给用户的代码时,如果没有用户代码的某些操作,就不可能知道它们是否被引用.

The EnvEval function should be marked in the documentation as triggering garbage collection, but it is not. CLIPS internally represents string, integers, floats, and other primitives similar to other languages (such as Java) which allow instances of classes such as String, Integer, and Float. As these values are dynamically created, they need to be subject to garbage collection when they are no longer used. Internally CLIPS uses reference counts to determine whether these values are referenced, but when these values are returned to a user's code it is not possible to know if they are referenced without some action from the user's code.

当您调用 EnvEval 时,它返回的值免于垃圾收集.下次调用 EnvEval 时,它不会免除.因此,如果您立即处理返回的值或将其保存(即为字符串分配存储空间并从 CLIPS 复制值或将多字段中的事实地址保存在数组中),那么您无需担心返回的值CLIPS 被后续的 EnvEval 调用垃圾回收.

When you call EnvEval, the value it returns is exempt from garbage collection. It is not exempt the next time EnvEval is called. So if you immediately process the value returned or save it (i.e. allocate storage for a string and copy the value from CLIPS or save the fact addresses from a multifield in an array), then you don't need to worry about the value returned by CLIPS being garbage collected by a subsequent EnvEval call.

如果您想执行一系列 EnvEval 调用(或其他可能触发垃圾收集的 CLIPS 函数)而不必担心值被垃圾收集,请将调用包装在 EnvIncrementGCLocks/EnvDecrementGCLocks 中

If you want to execute a series of EnvEval calls (or other CLIPS function which may trigger garbage collection) without having to worry about values being garbage collected, wrap the calls within EnvIncrementGCLocks/EnvDecrementGCLocks

EnvIncrementGCLocks(theEnv);
   ... Your Calls ...
EnvDecrementGCLocks(theEnv);  

在您进行调用时,所有返回到代码的值的垃圾收集将被暂时禁用,然后当您通过调用 EnvDecrementGCLocks 完成时,这些值将被垃圾收集.

Garbage collection for all the values returned to your code will be temporarily disabled while you make the calls and then when you finish by calling EnvDecrementGCLocks the values will be garbage collected.

在高级编程指南的第 1.4 节中有一些关于垃圾收集的附加信息.

There's some additional information on garbage collection in section 1.4 of the Advanced Programming Guide.

这篇关于剪辑多个 EnvEval 查询会使先前的结果对象无效?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆