Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

Cannot access multislot value in fact

Help
Rhen
2008-06-19
2013-04-25
  • Rhen
    Rhen
    2008-06-19

    I'm having trouble for getting multislot value in a fact that corresponding to spesific deftemplate
    When I try access the single value, there's no problem, I get the value. But when I try to retrieve the multivalued I got this notification :
    "An unhandled exception of type 'System.NullReferenceException' occurred in ManagedCLIPS.dll"

    I use this procedure Fact.GetSlot(slot_name).TypedValue.ValueToString()) to retrieve the value. Below is my C# code

    FactList.GetFirstFact(CLIPS).Retract();
    FactList flist = new FactList(CLIPS);
    foreach(Fact f in flist)
    {
        if (f.DefTemplate.Name == "coba")
        {
            DataObject o = f.GetSlot("banyak");
            CLIPS.PrintRouter("stdout", o.TypedValue.ValueToString()+"\n");
        }
    }

    The fact form is  :
    (coba (sedikit 0) (banyak 1 2 3))

    Is there a way for me to retrieve the value (i.e.: 1 2 3) in multivalued slot (banyak slot)?
    Thanks.

     
    • Izya K
      Izya K
      2008-06-19

      It was my fault. I've repaired this bug. See new release.

       
      • Rhen
        Rhen
        2008-06-20

        I've tried the new release but still I can't access the value in multivalued slot.
        I got this error report when debugging :

        Object reference not set to an instance of an object.
           at ManagedCLIPS.Multifield.IntValue(Int32 position)
           at CLIPSNet.CLIPSDataTypes.Multifield..ctor(Multifield m)
           at CLIPSNet.UserFunction.DataObject.get_TypedValue()
           at CLIPSDriver.Program.Main(String[] args) in D:\Data-college\Tugas Akhir\Application\CLIPSDriver\CLIPSDriver\Program.cs:line 32

        where my code are :
        line 31  DataObject o = f.GetSlot("banyak");
        line 32  Multifield m = (Multifield) o.TypedValue;

        but when I execute the program, not in debug mode I got this error :
        Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
           at ManagedCLIPS.Multifield.IntValue(Int32 position)
           at CLIPSNet.CLIPSDataTypes.Multifield..ctor(Multifield m)
           at CLIPSNet.UserFunction.DataObject.get_TypedValue()
           at CLIPSDriver.Program.Main(String[] args) in D:\Data-college\Tugas Akhir\Application\CLIPSDriver\CLIPSDriver\Program.cs:line 32

        Can someone help me ? :(
        I really need this .dll for finishing my first degree final project

         
    • Izya K
      Izya K
      2008-06-20

      How do you create and assert the fact?

       
    • Izya K
      Izya K
      2008-06-20

      Show me the whole code

       
      • Rhen
        Rhen
        2008-06-20

        This is my whole code :
                    CLIPSNet.Environment CLIPS = new CLIPSNet.Environment();
                    CLIPS.EnvClear();
                    CLIPS.Load("dummy.clp");
                    CLIPS.EnvReset();

                    Fact.AssertString(CLIPS, "(coba (banyak 1 2)(sedikit 0))");
                   
                CLIPS.EnvRun();
                    FactList.GetFirstFact(CLIPS).Retract();
                    FactList flist = new FactList(CLIPS);
                    foreach(Fact f in flist)
                    {
                        if (f.DefTemplate.Name == "coba")
                        {
                            if (f.DefTemplate.SlotMultiP("banyak"))
                            {
                                DataObject o = f.GetSlot("banyak");
                                try
                                {
                                    Multifield m = (Multifield) o.TypedValue;
                                    Console.WriteLine((m==null).ToString());

                                }
                                catch (Exception ex)
                                {

                                    Console.WriteLine(ex.Message);
                                    Console.WriteLine(ex.StackTrace);
                                    StreamWriter wr = new StreamWriter("fout.txt");
                                    wr.WriteLine(ex.Message);
                                    wr.WriteLine(ex.StackTrace);
                                    wr.WriteLine(ex.HelpLink);
                                    wr.Close();
                                }
                            }
                        }
                    }

        I just assert a simple fact i.e. (coba (banyak 1 2)(sedikit 0)) with
            Fact.AssertString()

        after I asserted the fact, I try to retrieve the value in the multislot with
           Multifield m = (Multifield) o.TypedValue;

        and I got error messages that I have wrote before. I wonder what's wrong with my code.

        This is my dummy.clp code :

        (deftemplate coba
            (multislot banyak)
            (slot sedikit)
        )
        (defrule startup
            (declare (salience 100))
                ?data <- (coba (banyak $?val) (sedikit ?val1))
            =>
                (printout t "rules fired" t)
        )

        I'm very looking forward and grateful for the help.

         
    • Izya K
      Izya K
      2008-06-21

      I can't find the cause of the error yet. But i suggest you to create fact by calling method CreateFact, setting its slots one by one and then asserting it. This is longer, but i have no error doing this way.

       
    • Rhen
      Rhen
      2008-06-21

      I think you have error in

      ManagedCLIPS.Multifield.IntValue(Int32 position)

      where it referenced to this line code on multifld.h

      #define GetMFValue(target,index)  (((struct field *) ((struct multifield *) (target))->theFields)[index-1].value)

      I want to help to fix it, but I can't understand the code ...

      Actually,my real problem is retrieving the fact from inference process and display all value in each slot to the .NET interface, i.e. TextBox, Label,etc. I'm inserting fact both from interface i.e. WindowsForm, and from result of firing rule in .clp file.  

      Can I have some example code how to define the fact, assign value in multivalued slot, asserting the fact, and retrieving back by CreateFact method ?

      I've tried CreateFact method, still I got the same error. Below is my entire code :

      CLIPSNet.Environment CLIPS = new CLIPSNet.Environment();
                  CLIPS.EnvClear();
                  CLIPS.Load("dummy.clp");
                  CLIPS.EnvReset();
                  CLIPS.EnvRun();
                  RouterEngine engine = new RouterEngine("stdout");
                  FactList.GetFirstFact(CLIPS).Retract();
                  FactList flist = new FactList(CLIPS);

                  DefTemplate t = DefTemplate.FindDefTemplate(CLIPS, "coba");
                  Fact ff = t.CreateFact();
                  Multifield value = new Multifield(2);
                  value.Add(new CLIPSNet.CLIPSDataTypes.Integer(1));
                  value.Add(new CLIPSNet.CLIPSDataTypes.Integer(2));
                  ff.SetSlot("banyak", value);
                  ff.SetSlot("sedikit", new CLIPSNet.CLIPSDataTypes.Integer(0));
                  ff.Assert();
                  foreach(Fact f in flist)
                  {
                      if (f.DefTemplate.Name == "coba")
                      {
                          if (f.DefTemplate.SlotMultiP("banyak"))
                          {
                              DataObject o = f.GetSlot("banyak");
                              try
                              {
                                  Multifield m = (Multifield) o.TypedValue; //error goes from this code o.TypedValue
                                  Console.WriteLine((m==null).ToString());
                              }
                              catch (Exception ex)
                              {

                                  Console.WriteLine(ex.Message);
                                  Console.WriteLine(ex.StackTrace);
                                  StreamWriter wr = new StreamWriter("fout.txt");
                                  wr.WriteLine(ex.Message);
                                  wr.WriteLine(ex.StackTrace);
                                  wr.WriteLine(ex.HelpLink);
                                  wr.Close();
                              }
                          }
                      }
                  } 

       
    • Izya K
      Izya K
      2008-06-23

      I've tried the following code, but I had no error.

      env.Build("(deftemplate coba (multislot banyak) (slot sedikit)) (defrule startup (declare (salience 100)) ?data <- (coba (banyak $?val) (sedikit ?val1)) => (printout t \&quot;rules fired\&quot; t)) ");
                  RouterEngine engine = env.CreateRouter("stdout", 20);
                  env.EnvReset();
                  env.EnvRun();
                  FactList fl = new FactList(env);
                 
                  DefTemplate d = DefTemplate.FindDefTemplate(env, "coba");
                  Fact f = d.CreateFact();
                  f.SetSlot("sedikit", new Integer(0));
                  Multifield m = new Multifield();
                  m.Add(new Integer(1));
                  m.Add(new Integer(2));
                  m.Add(new Integer(3));
                  f.SetSlot("banyak", m);
                  f.Assert();

                  foreach(Fact f1 in fl)
                  {
                      if(f1.DefTemplate.Name == "coba")
                      {
                          if (f1.DefTemplate.SlotMultiP("banyak"))
                          {
                              DataObject o = f1.GetSlot("banyak");
                              m = (Multifield)o.TypedValue;
                              env.PrintRouter("stdout", m.ValueToString());
                          }
                      }
                  }

       
    • Izya K
      Izya K
      2008-06-23

      Even retracting the initial-fact cause no error. Try to get the latest version from CVS. This may help.