Menu

Embedded Application - Find Fact in Rule and modify it on RHS of rule

Help
St Ko
2020-07-09
2020-07-16
  • St Ko

    St Ko - 2020-07-09

    Hey,

    I integrated this rule engine in my native application (sensor bus system in a building) and it works fine right now. What already is working:
    Building facts for apartments, rooms and sensors within the rooms. Then I store these facts within a map so that I can modify them later. I also know how to modify the fact which is executing the rule on the RHS but this is not what I want to achieve.

    I want to modify facts which where build previously in my native application based on a execution of a rule.
    The process chain would be sensor values change (native) --> sensor facts (e.g. Switch) change (native) --> rules are triggered --> room (deftemplate Aktivitaetswechsel with same apartment and room) and apartement (deftemplate Apartment_Status with same apartment) change as cause of certain rule.

    But I do not know how I can find these previously build facts in CLIPS language. These are my deftemplates I use. The slots apartment and room are fixed.

    Build(env, "(deftemplate Switch"
               "      (slot apartment)"
               "      (slot room)"
               "      (slot type)"
               "      (slot value))"
               "      (slot duration))");
    
    Build(env, "(deftemplate Aktivitaetswechsel"
               "      (slot apartment)"
               "      (slot room)"
               "      (slot type)"
               "      (slot timer_exceeded)"
               "      (slot status))");
    
    
    Build(env, "deftemplate Apartment_Status"
               "      (slot apartment)"
               "      (slot zu_hause))");
    

    Thanks in advance!

     
    • Gary Riley

      Gary Riley - 2020-07-13

      You can use the fact set query functions such as do-for-all-facts if you want to iterate over facts either in the actions of a rule or outside of a rule.

               CLIPS (6.31 6/12/19)
      CLIPS> 
      (deftemplate Apartment_Status
         (slot apartment)
         (slot zu_hause))
      CLIPS> 
      (assert (Apartment_Status (apartment 3A) (zu_hause yes))
              (Apartment_Status (apartment 3B) (zu_hause nein)))
      <Fact-2>
      CLIPS> 
      (do-for-all-facts ((?a Apartment_Status)) TRUE
         (printout t ?a:apartment " " ?a:zu_hause crlf))
      3A yes
      3B nein
      CLIPS> 
      

      From C, you can use the Eval function (similar to Build except for function calls) to execute the query.

       
  • St Ko

    St Ko - 2020-07-15

    That is not really what I wanted to achieve. I partially solve this issue via assigning each fact a fact_id. I store all facts within different maps in my embedded application. Over this fact_id I can find the fact in the map an modify it if there are changes in the embedded application. However this is solved using the UDF. For now I still have the issue that the UDF only gives the value of the given variables. Is there any way to receive the name of the variable also so that the UDF do different things depending on the given variable?

     
    • Gary Riley

      Gary Riley - 2020-07-15

      No, the symbolic names of variables are not available once the rule has been compiled. I'd suggest adding a separate argument to your UDF if if needs additional information to determine what to do.

       
  • St Ko

    St Ko - 2020-07-16

    Okay, I solved it via delivering a String before every variable and checking this string.

     

Log in to post a comment.