 
 (.add-facts kn "know" "agg-over" #js ["rule-id" "in-var" "agg-fun" "out-var"] #js [#js ["concat-overlap" "zz" "str" "ww"]])
 
+(.add-facts kn "know" "clauses" #js ["rule-id" "when|know|remember|forget" "clause-id" "name"] #js [#js ["limit-overlap" "when" "limit-get-foos" "foo"]
+                                                                                                    #js ["limit-overlap" "when" "limit-some-interval" "interval"]
+                                                                                                    #js ["limit-overlap" "remember" "limit-rem-frep" "frep"]])
+
+(.add-facts kn "know" "clause-fields" #js ["clause-id" "constant|variable" "key" "val"] #js [#js ["limit-get-foos" "variable" "x" "xx"]
+                                                                                             #js ["limit-get-foos" "variable" "y" "yy"]
+                                                                                             #js ["limit-some-interval" "variable" "lo" "xx"]
+                                                                                             #js ["limit-some-interval" "variable" "hi" "yy"]
+                                                                                             #js ["limit-some-interval" "variable" "in" "zz"]
+                                                                                             #js ["limit-rem-frep" "variable" "x" "xx"]
+                                                                                             #js ["limit-rem-frep" "variable" "o" "ord"]
+                                                                                             #js ["limit-rem-frep" "variable" "z" "zz"]])
+
+
+(.add-facts kn "know" "has-agg" #js ["rule-id" "limit-variable|constant" "limit" "ordinal" "ascending|descending"] #js [#js ["limit-overlap" "constant" 3 "ord" "descending"]])
+
 
 (def flows (compile kn))
 


              ;; make inputs
              constraints (for [[_ clause-type clause-id name] sorted-clauses
                                     :when (= clause-type "when")]
                                 (let [fields (get @clause-id->fields clause-id)]
                                   (case name
                                     "=constant" (let [variable (first (for [[_ field-type key val] fields
                                                                             :when (= key "variable")]
                                                                         val))
                                                       constant (first (for [[_ field-type key val] fields
                                                                             :when (= key "constant")]
                                                                         val))
                                                       ix (get var->ix variable)]
                                                   (btree/constant constant ix))
                                     "=variable" (let [variable-a (first (for [[_ field-type key val] fields
                                                                               :when (= key "variable-a")]
                                                                           val))
                                                       variable-b (first (for [[_ field-type key val] fields
                                                                               :when (= key "variable-b")]
                                                                           val))
                                                       ix-a (get var->ix variable-a)
                                                       ix-b (get var->ix variable-b)]
                                                   (btree/equal #js [ix-a ix-b]))
                                     "=function" (let [variable (first (for [[_ field-type key val] fields
                                                                             :when (= key "variable")]
                                                                         val))
                                                       js (first (for [[_ field-type key val] fields
                                                                       :when (= key "js")]
                                                                   val))
                                                       result-ix (get var->ix variable)
                                                       args (for [var vars
                                                                  :when (>= (.indexOf js var) 0)]
                                                              var)
                                                       arg-ixes (map var->ix args)
                                                       fun (apply js/Function (conj (vec args) (str "return (" js ");")))]
                                                   (btree/function fun result-ix (into-array arg-ixes)))
                                     "filter" (let [js (first (for [[_ field-type key val] fields
                                                                    :when (= key "js")]
                                                                val))
                                                    args (for [var vars
                                                               :when (>= (.indexOf js var) 0)]
                                                           var)
                                                    arg-ixes (map var->ix args)
                                                    fun (apply js/Function (conj (vec args) (str "return (" js ");")))]
                                                (btree/filter fun (into-array arg-ixes)))
                                     "interval" (let [in (first (for [[_ field-type key val] fields
                                                                      :when (= key "in")]
                                                                  val))
                                                      in-ix (get var->ix in)
                                                      lo (first (for [[_ field-type key val] fields
                                                                      :when (= key "lo")]
                                                                  val))
                                                      lo-ix (get var->ix lo)
                                                      hi (first (for [[_ field-type key val] fields
                                                                      :when (= key "hi")]
                                                                  val))
                                                      hi-ix (get var->ix hi)]
                                                  (btree/interval in-ix lo-ix hi-ix))
                                     (let [clause-vars&keys (sort-by (fn [[val key]] (var->ix val))
                                                                     (for [[_ field-type key val] fields]
                                                                       [val key]))
                                           clause-vars (map first clause-vars&keys)
                                           clause-vars-ixes (map var->ix clause-vars)
                                           clause-keys (map second clause-vars&keys)
                                           index (.get-or-create-index kn "know" name (into-array clause-keys))]
                                       (swap! kind->name->rules update-in ["know" name] #(conj (or % #{}) rule-id))
                                       (btree/contains (btree/iterator index) (into-array clause-vars-ixes))))))

              ;; make solver
              solver (btree/solver num-vars (into-array constraints))

(.get-or-create-index kn "know" "frip" #js ["x" "w"])

(.get-or-create-index kn "know" "frop" #js ["x" "o" "z" "w"])

(.get-or-create-index kn "know" "frep" #js ["x" "o" "z"])
)
