Search code examples
clips

How to convert String to Float


I have a simple dumbed down example. I have a prop template to store parameters and its value from different servers. The property value could either be String or numeric (Integer or Float). Currently, the "collector" that reads the properties from the systems generates the facts with the column value as String.

(deftemplate prop (slot serverid) (slot name) (slot value))
(assert (prop (serverid "ppn45r07vm_0") (name "email.encoding") (value "utf-8")))
(assert (prop (serverid "ppn45r07vm_0") (name "inventory.safety.threshold") (value "99.0")))
(assert (prop (serverid "ppn45r55vm_0") (name "inventory.safety.threshold") (value "993.1")))

(defrule check-range
    (prop (serverid ?s) (name "inventory.safety.threshold") (value ?v))
    (test (> (float ?v) 100.0) )
=> 
    (printout t "safety threshold on server " ?s " is set too high at " ?v crlf)
)       

My question -- how do I convert the String value into either a Float or Integer value so that I can perform range checks, etc. The sample code above works in JESS because JESS's float function takes in a String argument and returns a Float. CLIPS's float function takes in a number and returns a float. I could not find a similar CLIPS function that converts String to Float.

Just for completeness, in CLIPS, I get the following error

CLIPS> (defrule check-range
    (prop (serverid ?s) (name "inventory.safety.threshold") (value ?v))
    (test (> (float ?v) 100.0) )
=> 
    (printout t "safety threshold on server " ?s " is set too high at " ?v crlf)
)       
[ARGACCES5] Function float expected argument #1 to be of type float

[DRIVE1] This error occurred in the join network
   Problem resides in associated join
      Of pattern #1 in rule check-range

[ARGACCES5] Function float expected argument #1 to be of type float

[DRIVE1] This error occurred in the join network
   Problem resides in associated join
      Of pattern #1 in rule check-range

Apologies if there is an obvious answer. Thanks in advance for any help.


Solution

  • You can overload the float function to get similar behavior to Jess with strings:

    CLIPS> (float "3")
    [ARGACCES5] Function float expected argument #1 to be of type integer or float
    CLIPS> 
    (defmethod float ((?s STRING))
       (float (string-to-field ?s)))
    CLIPS> (float "3")
    3.0
    CLIPS>