2017-03-07 4 views
1

Ich arbeite mit CLIPS.NET und frage mich, wie ich auf die Agenda in Clips zugreifen kann.Get Agenda in CLIPS

Ich möchte einige Eingabewerte haben und die Clips laufen lassen, damit sie basierend auf den Eingabewerten eine Lösung generieren können. Aber ich möchte auch sehen, welche Regeln genau ausgelöst werden. Ich jetzt so etwas wie dieses das Problem

(deftemplate MAIN::action 
    (slot name (default ?NONE))) 

(deftemplate MAIN::input 
    (slot name) 
    (slot value (default ?NONE))) 

(defrule MAIN::rule0 
    (input (name test-input) (value 1)) 
=> 
    (assert (action (name do-something))) 
) 

haben, ist verwende ich kippe (Agenda), weil das druckt nur etwas an der Konsole und gibt mir keine Zeichenfolge i mit oder etwas wie das funktionieren kann. Also wie kann ich die agenda bekommen? Oder muss ich in jeder Regel eine neue Tatsache erstellen, um zu sehen, welche Regeln ausgeführt wurden (scheint etwas unbequem zu sein)? (Vorerst muss ich nur die Namen der Regeln)

UPDATE

mein Versuch auf Funktion "all-next-Aktivierung" (Arbeits jetzt):

void AllNextActivationFunction(
    void *theEnv, 
    DATA_OBJECT_PTR returnValue) 
    { 
    unsigned long count; 
    struct multifield *theList; 
    void *act; 


    if (EnvArgCountCheck(theEnv, "all-next-activation", EXACTLY, 0) == -1) 
     { 
     EnvSetMultifieldErrorValue(theEnv, returnValue); 
     return; 
     } 

    // Count activations 
    for (act = EnvGetNextActivation(theEnv, NULL), count = 0; 
     act != NULL; 
     act = EnvGetNextActivation(theEnv, act), count++) 
     { /* Do Nothing */ } 

    // Create the multifield 
    SetpType(returnValue, MULTIFIELD); 
    SetpDOBegin(returnValue, 1); 
    SetpDOEnd(returnValue, (long)count); 
    theList = (struct multifield *) EnvCreateMultifield(theEnv, count); 
    SetpValue(returnValue, (void *)theList); 

    // Store values in multifield 
    for (act = EnvGetNextActivation(theEnv, NULL), count = 1; 
     act != NULL; 
     act = EnvGetNextActivation(theEnv, act), count++) 
     { 
     SetMFType(theList, count, SYMBOL); 
     SetMFValue(theList, count, EnvAddSymbol(theEnv, EnvGetActivationName(theEnv, act))); 
     } 
    } 


void EnvUserFunctions(
    void *environment) 
    { 
    EnvDefineFunction2(environment, "next-activation", 'w', PTIEF NextActivationFunction, "NextActivationFunction", "00"); 
    EnvDefineFunction2(environment, "all-next-activation", 'm', PTIEF AllNextActivationFunction, "AllNextActivationFunction", "00"); 
    } 

Antwort

2

, würden Sie entweder Sie müssen die .NET-API um einige der C-Funktionen erweitern, die es Ihnen ermöglichen, über die Aktivierungen zu iterieren und Informationen von ihnen zu entnehmen oder eine benutzerdefinierte Funktion in CLIPS hinzuzufügen und die Eval-Methode von .NET zum Aufrufen dieser CLIPS-Funktion zu verwenden. Zum Beispiel, hier ist Code, den Sie zu dem userfunctions.c hinzufügen können, die den Namen der nächsten Aktivierung zurück:

void *NextActivationFunction(
    void *theEnv) 
    { 
    void *act; 

    if (EnvArgCountCheck(theEnv,"next-activation",EXACTLY,0) == -1) 
    { return EnvFalseSymbol(theEnv); } 

    act = EnvGetNextActivation(theEnv,NULL); 

    if (act == NULL) 
    { return EnvFalseSymbol(theEnv); } 
    else 
    { return EnvAddSymbol(theEnv,EnvGetActivationName(theEnv,act)); } 
    } 

void EnvUserFunctions(
    void *environment) 
    { 
    EnvDefineFunction2(environment,"next-activation", 'w', PTIEF NextActivationFunction, "NextActivationFunction", "00"); 
    } 

rekompilieren CLIPS mit diesem Code können Sie diese Funktion innerhalb CLIPS verwenden:

CLIPS> (next-activation) 
FALSE 
CLIPS> (defrule foo =>) 
CLIPS> (defrule bar =>) 
CLIPS> (next-activation) 
bar 
CLIPS> (run 1) 
CLIPS> (next-activation) 
foo 
CLIPS> 

Oder von .NET mit der Eval-Methode:

clips.Eval("(next-activation)"); 
+0

danke. Gibt es eine Möglichkeit, die nächste Aktivierung auf einmal zu erhalten? Ich habe etwas versucht (ich habe die Frage aktualisiert), aber es funktioniert nicht – MrWoffle

+1

1) Es besteht keine Notwendigkeit, SaveCurrentModule aufzurufen, aber wenn Sie einen nachfolgenden Aufruf von RestoreCurrentModule benötigen. 2) Starten Sie die zweite Schleife mit count auf 1. SetMFType und SetMFValue Indizes beginnen bei 1. 3) Ersetzen Sie den SetMFValue Aufruf mit SetMFValue (theList, count, EnvAddSymbol (theEnv, EnvGetActivationName (theEnv, act))); –

+0

danke! (Ich habe den Code in der Frage so aktualisiert, dass er jetzt funktioniert) – MrWoffle