剪辑在 C++ 中创建多场
Clips create Multifield in c++
我想创建如下所示的模板事实:
; initial and final state of a single IF instance
(deftemplate InitialAndFinalState
(slot initial_state)
(multislot final_state)
)
使用 c++ 接口,我按以下方式使用:
void* ifs_template = EnvFindDeftemplate(clips_environment_,
"InitialAndFinalState");
void* ifs_fact = EnvCreateFact(clips_environment_, ifs_template);
if (ifs_fact != NULL) {
DATA_OBJECT field;
field.type = FACT_ADDRESS;
field.value =
addSpinWaveToClipsEnvironment(initial_state);
EnvPutFactSlot(clips_environment_, ifs_fact, "initial_state", &field);
void* multifield_ptr = EnvCreateMultifield(clips_environment_,
final_state.size());
for (unsigned int i = 0; i < final_state.size(); ++i) {
SetMFType(multifield_ptr, i + 1, FACT_ADDRESS);
SetMFValue(multifield_ptr, i + 1,
addSpinWaveToClipsEnvironment(final_state[i]));//);
}
DATA_OBJECT final_states;
SetDOBegin(final_states, 1);
SetDOEnd(final_states, final_state.size());
SetType(final_states, MULTIFIELD);
SetValue(final_states, multifield_ptr);
EnvPutFactSlot(clips_environment_, ifs_fact, "final_state", &final_states);
EnvAssert(clips_environment_, ifs_fact);
}
addSpinWaveToClipsEnviroment 函数将添加一个 SpinWave 事实或找到现有的事实和 return 一个事实地址。
void* DecayGenerator::addSpinWaveToClipsEnvironment(const SpinWave& spinwave) {
std::vector<std::pair<std::string, int> > spin_qn_name_value_pairs;
for (auto spin_like_qn = spinwave.spin_like_quantum_numbers_.begin();
spin_like_qn != spinwave.spin_like_quantum_numbers_.end();
++spin_like_qn) {
spin_qn_name_value_pairs.push_back(
std::make_pair(spin_like_qn->first,
addSpinQuantumNumberToClipsEnvironment(spin_like_qn->second)));
}
std::stringstream clips_query;
std::stringstream values_part;
values_part << "(explode$ \"";
clips_query << "(find-spinwave-fact-list (explode$ \"";
for (auto spin_like_qn = spin_qn_name_value_pairs.begin();
spin_like_qn != spin_qn_name_value_pairs.end(); ++spin_like_qn) {
clips_query << "\\"" << spin_like_qn->first << "\\" ";
values_part << spin_like_qn->second << " ";
}
for (auto int_like_qn = spinwave.integer_like_quantum_numbers_.begin();
int_like_qn != spinwave.integer_like_quantum_numbers_.end();
++int_like_qn) {
clips_query << "\\"" << int_like_qn->first << "\\" ";
values_part << int_like_qn->second << " ";
}
for (auto double_like_qn = spinwave.double_like_quantum_numbers_.begin();
double_like_qn != spinwave.double_like_quantum_numbers_.end();
++double_like_qn) {
clips_query << "\\"" << double_like_qn->first << "\\" ";
values_part << double_like_qn->second << " ";
}
values_part << "\")";
clips_query << "\") " << values_part.str() << ")";
DATA_OBJECT found_spin_waves_facts;
EnvEval(clips_environment_, clips_query.str().c_str(),
&found_spin_waves_facts);
void* spinwave_fact;
if (0 < GetDOLength(found_spin_waves_facts)) {
spinwave_fact = GetMFValue(GetValue(found_spin_waves_facts), 1);
}
else {
void* spinwave_template = EnvFindDeftemplate(clips_environment_,
"SpinWave");
// set the facts
spinwave_fact = EnvCreateFact(clips_environment_, spinwave_template);
if (spinwave_fact != NULL) {
unsigned int total_qn_count = spinwave.spin_like_quantum_numbers_.size()
+ spinwave.integer_like_quantum_numbers_.size()
+ spinwave.double_like_quantum_numbers_.size();
void* qn_names_ptr = EnvCreateMultifield(clips_environment_,
total_qn_count);
void* qn_values_ptr = EnvCreateMultifield(clips_environment_,
total_qn_count);
unsigned int counter(1);
for (auto spin_like_qn = spin_qn_name_value_pairs.begin();
spin_like_qn != spin_qn_name_value_pairs.end(); ++spin_like_qn) {
SetMFType(qn_names_ptr, counter, STRING);
SetMFValue(qn_names_ptr, counter,
EnvAddSymbol(clips_environment_, spin_like_qn->first.c_str()));
SetMFType(qn_values_ptr, counter, INTEGER);
SetMFValue(qn_values_ptr, counter,
EnvAddLong(clips_environment_, spin_like_qn->second));
++counter;
}
for (auto int_like_qn = spinwave.integer_like_quantum_numbers_.begin();
int_like_qn != spinwave.integer_like_quantum_numbers_.end();
++int_like_qn) {
SetMFType(qn_names_ptr, counter, STRING);
SetMFValue(qn_names_ptr, counter,
EnvAddSymbol(clips_environment_, int_like_qn->first.c_str()));
SetMFType(qn_values_ptr, counter, INTEGER);
SetMFValue(qn_values_ptr, counter,
EnvAddLong(clips_environment_, int_like_qn->second));
++counter;
}
for (auto double_like_qn = spinwave.double_like_quantum_numbers_.begin();
double_like_qn != spinwave.double_like_quantum_numbers_.end();
++double_like_qn) {
SetMFType(qn_names_ptr, counter, STRING);
SetMFValue(qn_names_ptr, counter,
EnvAddSymbol(clips_environment_, double_like_qn->first.c_str()));
SetMFType(qn_values_ptr, counter, INTEGER);
SetMFValue(qn_values_ptr, counter,
EnvAddLong(clips_environment_, double_like_qn->second));
++counter;
}
DATA_OBJECT qn_names;
DATA_OBJECT qn_values;
SetType(qn_names, MULTIFIELD);
SetValue(qn_names, qn_names_ptr);
SetDOBegin(qn_names, 1);
SetDOEnd(qn_names, total_qn_count);
SetType(qn_values, MULTIFIELD);
SetValue(qn_values, qn_values_ptr);
SetDOBegin(qn_values, 1);
SetDOEnd(qn_values, total_qn_count);
EnvPutFactSlot(clips_environment_, spinwave_fact, "quantum_number_names",
&qn_names);
EnvPutFactSlot(clips_environment_, spinwave_fact, "quantum_number_values",
&qn_values);
EnvAssignFactSlotDefaults(clips_environment_, spinwave_fact);
EnvAssert(clips_environment_, spinwave_fact);
}
}
return spinwave_fact;
}
问题是 final_state 多槽变量仅在某些情况下被正确填充,例如,如果我有 1、3、4、6... 值而不是 2 和 5!当我想在里面放两个时,多槽里面只有一些接近 0 的浮点数。如果我使用 5 那么它在断言事实时崩溃。对我来说似乎是一些内存分配问题。我调试了 c++ 代码,它向 EnvCreateMultifield 函数传递了一个适当的大小值。我真的不知道是什么原因造成的。有什么想法吗?
正如 Gary 在评论中提到的那样,用
包装该函数
EnvIncrementGCLocks/EnvDecrementGCLocks
解决问题。
我想创建如下所示的模板事实:
; initial and final state of a single IF instance
(deftemplate InitialAndFinalState
(slot initial_state)
(multislot final_state)
)
使用 c++ 接口,我按以下方式使用:
void* ifs_template = EnvFindDeftemplate(clips_environment_,
"InitialAndFinalState");
void* ifs_fact = EnvCreateFact(clips_environment_, ifs_template);
if (ifs_fact != NULL) {
DATA_OBJECT field;
field.type = FACT_ADDRESS;
field.value =
addSpinWaveToClipsEnvironment(initial_state);
EnvPutFactSlot(clips_environment_, ifs_fact, "initial_state", &field);
void* multifield_ptr = EnvCreateMultifield(clips_environment_,
final_state.size());
for (unsigned int i = 0; i < final_state.size(); ++i) {
SetMFType(multifield_ptr, i + 1, FACT_ADDRESS);
SetMFValue(multifield_ptr, i + 1,
addSpinWaveToClipsEnvironment(final_state[i]));//);
}
DATA_OBJECT final_states;
SetDOBegin(final_states, 1);
SetDOEnd(final_states, final_state.size());
SetType(final_states, MULTIFIELD);
SetValue(final_states, multifield_ptr);
EnvPutFactSlot(clips_environment_, ifs_fact, "final_state", &final_states);
EnvAssert(clips_environment_, ifs_fact);
}
addSpinWaveToClipsEnviroment 函数将添加一个 SpinWave 事实或找到现有的事实和 return 一个事实地址。
void* DecayGenerator::addSpinWaveToClipsEnvironment(const SpinWave& spinwave) {
std::vector<std::pair<std::string, int> > spin_qn_name_value_pairs;
for (auto spin_like_qn = spinwave.spin_like_quantum_numbers_.begin();
spin_like_qn != spinwave.spin_like_quantum_numbers_.end();
++spin_like_qn) {
spin_qn_name_value_pairs.push_back(
std::make_pair(spin_like_qn->first,
addSpinQuantumNumberToClipsEnvironment(spin_like_qn->second)));
}
std::stringstream clips_query;
std::stringstream values_part;
values_part << "(explode$ \"";
clips_query << "(find-spinwave-fact-list (explode$ \"";
for (auto spin_like_qn = spin_qn_name_value_pairs.begin();
spin_like_qn != spin_qn_name_value_pairs.end(); ++spin_like_qn) {
clips_query << "\\"" << spin_like_qn->first << "\\" ";
values_part << spin_like_qn->second << " ";
}
for (auto int_like_qn = spinwave.integer_like_quantum_numbers_.begin();
int_like_qn != spinwave.integer_like_quantum_numbers_.end();
++int_like_qn) {
clips_query << "\\"" << int_like_qn->first << "\\" ";
values_part << int_like_qn->second << " ";
}
for (auto double_like_qn = spinwave.double_like_quantum_numbers_.begin();
double_like_qn != spinwave.double_like_quantum_numbers_.end();
++double_like_qn) {
clips_query << "\\"" << double_like_qn->first << "\\" ";
values_part << double_like_qn->second << " ";
}
values_part << "\")";
clips_query << "\") " << values_part.str() << ")";
DATA_OBJECT found_spin_waves_facts;
EnvEval(clips_environment_, clips_query.str().c_str(),
&found_spin_waves_facts);
void* spinwave_fact;
if (0 < GetDOLength(found_spin_waves_facts)) {
spinwave_fact = GetMFValue(GetValue(found_spin_waves_facts), 1);
}
else {
void* spinwave_template = EnvFindDeftemplate(clips_environment_,
"SpinWave");
// set the facts
spinwave_fact = EnvCreateFact(clips_environment_, spinwave_template);
if (spinwave_fact != NULL) {
unsigned int total_qn_count = spinwave.spin_like_quantum_numbers_.size()
+ spinwave.integer_like_quantum_numbers_.size()
+ spinwave.double_like_quantum_numbers_.size();
void* qn_names_ptr = EnvCreateMultifield(clips_environment_,
total_qn_count);
void* qn_values_ptr = EnvCreateMultifield(clips_environment_,
total_qn_count);
unsigned int counter(1);
for (auto spin_like_qn = spin_qn_name_value_pairs.begin();
spin_like_qn != spin_qn_name_value_pairs.end(); ++spin_like_qn) {
SetMFType(qn_names_ptr, counter, STRING);
SetMFValue(qn_names_ptr, counter,
EnvAddSymbol(clips_environment_, spin_like_qn->first.c_str()));
SetMFType(qn_values_ptr, counter, INTEGER);
SetMFValue(qn_values_ptr, counter,
EnvAddLong(clips_environment_, spin_like_qn->second));
++counter;
}
for (auto int_like_qn = spinwave.integer_like_quantum_numbers_.begin();
int_like_qn != spinwave.integer_like_quantum_numbers_.end();
++int_like_qn) {
SetMFType(qn_names_ptr, counter, STRING);
SetMFValue(qn_names_ptr, counter,
EnvAddSymbol(clips_environment_, int_like_qn->first.c_str()));
SetMFType(qn_values_ptr, counter, INTEGER);
SetMFValue(qn_values_ptr, counter,
EnvAddLong(clips_environment_, int_like_qn->second));
++counter;
}
for (auto double_like_qn = spinwave.double_like_quantum_numbers_.begin();
double_like_qn != spinwave.double_like_quantum_numbers_.end();
++double_like_qn) {
SetMFType(qn_names_ptr, counter, STRING);
SetMFValue(qn_names_ptr, counter,
EnvAddSymbol(clips_environment_, double_like_qn->first.c_str()));
SetMFType(qn_values_ptr, counter, INTEGER);
SetMFValue(qn_values_ptr, counter,
EnvAddLong(clips_environment_, double_like_qn->second));
++counter;
}
DATA_OBJECT qn_names;
DATA_OBJECT qn_values;
SetType(qn_names, MULTIFIELD);
SetValue(qn_names, qn_names_ptr);
SetDOBegin(qn_names, 1);
SetDOEnd(qn_names, total_qn_count);
SetType(qn_values, MULTIFIELD);
SetValue(qn_values, qn_values_ptr);
SetDOBegin(qn_values, 1);
SetDOEnd(qn_values, total_qn_count);
EnvPutFactSlot(clips_environment_, spinwave_fact, "quantum_number_names",
&qn_names);
EnvPutFactSlot(clips_environment_, spinwave_fact, "quantum_number_values",
&qn_values);
EnvAssignFactSlotDefaults(clips_environment_, spinwave_fact);
EnvAssert(clips_environment_, spinwave_fact);
}
}
return spinwave_fact;
}
问题是 final_state 多槽变量仅在某些情况下被正确填充,例如,如果我有 1、3、4、6... 值而不是 2 和 5!当我想在里面放两个时,多槽里面只有一些接近 0 的浮点数。如果我使用 5 那么它在断言事实时崩溃。对我来说似乎是一些内存分配问题。我调试了 c++ 代码,它向 EnvCreateMultifield 函数传递了一个适当的大小值。我真的不知道是什么原因造成的。有什么想法吗?
正如 Gary 在评论中提到的那样,用
包装该函数EnvIncrementGCLocks/EnvDecrementGCLocks
解决问题。