如何使用Java API获取CLIPS事实的字段数据?
How to get the field data of a CLIPS fact using the Java API?
假设我有一些 plain CLIPS 事实(无插槽):
(deffacts happyFacts
(happy Peter)
(happy Alex)
(happy Mary))
使用 Java API (CLIPSJNI),我可以按如下方式检索这些事实:
MultifieldValue mv = (MultifieldValue) clips.eval("(find-all-facts ((?f happy)) TRUE)");
然后我可以检索第一个单独的事实如下:
FactAddressValue fact = (FactAddressValue) mv.multifieldValue().get(0);
如果那个事实有命名插槽,我就可以按如下方式获得字段数据:
fact.getFactSlot("someSlot")
但它没有插槽;那么,如何检索它的字段值(在本例中,Peter
)?
对于 CLIPSJNI 0.5,修改 net_sf_cilpsrules_jni_Environment.c 中的 Java_net_sf_clipsrules_jni_Environment_getFactSlot 以允许将空值作为插槽名称传递:
JNIEXPORT jobject JNICALL Java_net_sf_clipsrules_jni_Environment_getFactSlot(
JNIEnv *env,
jclass javaClass,
jobject javaEnv,
jlong clipsEnv,
jlong clipsFact,
jstring slotName)
{
jobject rv;
DATA_OBJECT theDO;
void *theCLIPSEnv = JLongToPointer(clipsEnv);
const char *cSlotName = NULL;
if (slotName != NULL)
{ cSlotName = (*env)->GetStringUTFChars(env,slotName,NULL); }
void *oldContext = SetEnvironmentContext(theCLIPSEnv,(void *) env);
EnvGetFactSlot(JLongToPointer(clipsEnv),JLongToPointer(clipsFact),(char *) cSlotName,&theDO);
if (slotName != NULL)
{ (*env)->ReleaseStringUTFChars(env,slotName,cSlotName); }
rv = ConvertDataObject(env,javaEnv,theCLIPSEnv,&theDO);
SetEnvironmentContext(JLongToPointer(clipsEnv),oldContext);
return rv;
}
然后您可以将空值传递给 return 隐含插槽:
public static void main(String args[])
{
Environment clips;
clips = new Environment();
clips.build("(deffacts happyFacts " +
" (happy Peter)" +
" (happy Alex)" +
" (happy Mary))");
clips.reset();
clips.eval("(facts)");
MultifieldValue mv = (MultifieldValue) clips.eval("(find-all-facts ((?f happy)) TRUE)");
FactAddressValue fact = (FactAddressValue) mv.multifieldValue().get(0);
try
{
System.out.println("Slot value is " + fact.getFactSlot(null));
}
catch (Exception e)
{
e.printStackTrace();
}
}
假设我有一些 plain CLIPS 事实(无插槽):
(deffacts happyFacts
(happy Peter)
(happy Alex)
(happy Mary))
使用 Java API (CLIPSJNI),我可以按如下方式检索这些事实:
MultifieldValue mv = (MultifieldValue) clips.eval("(find-all-facts ((?f happy)) TRUE)");
然后我可以检索第一个单独的事实如下:
FactAddressValue fact = (FactAddressValue) mv.multifieldValue().get(0);
如果那个事实有命名插槽,我就可以按如下方式获得字段数据:
fact.getFactSlot("someSlot")
但它没有插槽;那么,如何检索它的字段值(在本例中,Peter
)?
对于 CLIPSJNI 0.5,修改 net_sf_cilpsrules_jni_Environment.c 中的 Java_net_sf_clipsrules_jni_Environment_getFactSlot 以允许将空值作为插槽名称传递:
JNIEXPORT jobject JNICALL Java_net_sf_clipsrules_jni_Environment_getFactSlot(
JNIEnv *env,
jclass javaClass,
jobject javaEnv,
jlong clipsEnv,
jlong clipsFact,
jstring slotName)
{
jobject rv;
DATA_OBJECT theDO;
void *theCLIPSEnv = JLongToPointer(clipsEnv);
const char *cSlotName = NULL;
if (slotName != NULL)
{ cSlotName = (*env)->GetStringUTFChars(env,slotName,NULL); }
void *oldContext = SetEnvironmentContext(theCLIPSEnv,(void *) env);
EnvGetFactSlot(JLongToPointer(clipsEnv),JLongToPointer(clipsFact),(char *) cSlotName,&theDO);
if (slotName != NULL)
{ (*env)->ReleaseStringUTFChars(env,slotName,cSlotName); }
rv = ConvertDataObject(env,javaEnv,theCLIPSEnv,&theDO);
SetEnvironmentContext(JLongToPointer(clipsEnv),oldContext);
return rv;
}
然后您可以将空值传递给 return 隐含插槽:
public static void main(String args[])
{
Environment clips;
clips = new Environment();
clips.build("(deffacts happyFacts " +
" (happy Peter)" +
" (happy Alex)" +
" (happy Mary))");
clips.reset();
clips.eval("(facts)");
MultifieldValue mv = (MultifieldValue) clips.eval("(find-all-facts ((?f happy)) TRUE)");
FactAddressValue fact = (FactAddressValue) mv.multifieldValue().get(0);
try
{
System.out.println("Slot value is " + fact.getFactSlot(null));
}
catch (Exception e)
{
e.printStackTrace();
}
}