Java 作为流程的函数的动态(树)结构(以及Clojure中的实现)

Java 作为流程的函数的动态(树)结构(以及Clojure中的实现),java,clojure,tree,expert-system,Java,Clojure,Tree,Expert System,这听起来可能很奇怪,因为我无法找到一个确切的术语来描述我正在尝试做的事情 我正在开发一个应用程序,在给定一组规则(很容易翻译成函数)和输入/输出对(不容易翻译成代码)的情况下,它允许构建一个规则树,应用于给定的输入,以达到给定的输出 它与专家系统类似,只是目标不是确定“更好”(通过某种质量)的规则/功能树(实际上,将输入映射到输出本身是次要的),而是能够根据一些限制或业务规则构建这些树 我正试图在Clojure做这件事,但我也会感谢更多的一般性建议,因为我甚至不知道如何简单地称之为这类事情 说到

这听起来可能很奇怪,因为我无法找到一个确切的术语来描述我正在尝试做的事情

我正在开发一个应用程序,在给定一组规则(很容易翻译成函数)和输入/输出对(不容易翻译成代码)的情况下,它允许构建一个规则树,应用于给定的输入,以达到给定的输出

它与专家系统类似,只是目标不是确定“更好”(通过某种质量)的规则/功能树(实际上,将输入映射到输出本身是次要的),而是能够根据一些限制或业务规则构建这些树

我正试图在Clojure做这件事,但我也会感谢更多的一般性建议,因为我甚至不知道如何简单地称之为这类事情

说到细节,我应该有一个大平面的细节地图。 我有一个很长的函数列表,我将其转换为几乎相同的功能:每个函数都采用这个大平面的细节图,并将规则应用于该规则所涉及的任何值。函数有副作用(记录它所做的事情),并且,假定,该树结构使用单个布尔输出来确定进入哪个分支(如果树在此函数上分裂)

我的想法是,我可以接受一个函数,并将其声明为树的根。然后取另一个函数并将其声明为下一个要执行的函数,或者取两个函数并将它们声明为根函数的下两个分支,具体取决于根函数的输出。等等等等。 我需要能够做很多次我想做的事情,生成一棵符合某些要求的树。 我将做所有的逻辑,但我需要一个结构,允许我将函数树(我甚至可以自己构造,只要我只需要指定它作为一个简单的列表)应用到给定的输入映射,而不必为我要做的每一棵树手动编写整个过程树

现实生活中的例子是一个大型树状数据结构(我们可以很容易地将输入平铺),每个客户机在处理(到达输出)时都可以根据自己的一组规则来描述它(函数的副作用)

这个“过程”是否有比这个长描述更常见的名称? Java/Clojure有什么功能可以使用吗?或者我应该自己尝试吗? 对于那些了解Clojure的人,我基本上需要一个(->)家族的变体,它可以接受一个函数树,比如

(tree-> 
input-buffer side-effect-buffer output-buffer (f1 (f2 f4 (f5 f7)) (f3 f6)))
编辑以下内容:添加示例: 这只是我正在寻找的更通用解决方案的一部分:

一款基于炼金术的(迷你)游戏(更一般地说,是真正的化学和炼金术的混合)。 在这种情况下,输入被分组为混合物的可测量/可观察特征,例如:

(def concoction 
    {:observable {:color {:r 50 :g 50 :b 50} :opacity 50}
     :measurable {:acidity 50 :density 50 :fluidity 50 :composition "TO DO"}
     :testable {:duration 10 :known-effects [list of maps] :safety 10 :after "TO DO"}})
输出是一个映射向量,每个映射向量类似于:

{:ingredient "ingredient-a" :amount 20 :application {:type "mix" :order 0}}
(defn apply-logic [input logic-to-apply]
    (let [chalist (apply (:input logic-to-apply) input)
          out (apply (:logic logic-to-apply) chalist)]
     (info-out (apply (:format logic-to-apply) out))
     (return-grade out chalist))))
; info-out uses info-output and output variables set with let somewhere outside
(独立)功能通常由3部分组成:

  • 获得混合物的一个(或多个)特征
  • 对所选特征应用一些限制性逻辑(结果混合物中成分单独作用表、应用类型表或两种或多种成分组合作用表中的少量条目)
  • 将处理后的特征记录到共享日志/信息输出中
  • 将逻辑应用的结果追加到输出
  • 返回布尔值(现在是int,稍后将是int),表示此步骤在生成输出方面的成功程度
  • 我改变了一点逻辑,所以现在我只有一个函数将给定的逻辑应用于输入(而不是几乎无限量的类似函数),类似于:

    {:ingredient "ingredient-a" :amount 20 :application {:type "mix" :order 0}}
    
    (defn apply-logic [input logic-to-apply]
        (let [chalist (apply (:input logic-to-apply) input)
              out (apply (:logic logic-to-apply) chalist)]
         (info-out (apply (:format logic-to-apply) out))
         (return-grade out chalist))))
    ; info-out uses info-output and output variables set with let somewhere outside
    
    然后我将有一个逻辑树来应用,而不是函数:

    (def tree-1112 '(logic1 
                     (logic2 
                      (logic3 
                       (logic4 logic5))) 
                     (logic6 
                       (logic7) 
                       (logic8 
                        (logic9)))))
    
    以及某种应用树逻辑:

    (defn apply-tree-logic [some-tree input]
     (if (apply-logic input (take-root some-tree)) 
      (apply-tree-logic (take-branch first some-tree) input)
      (apply-tree-logic (take-branch last some-tree) input))
    
    实际上,如果我能完全按照我在这些例子中介绍的那样去做的话,它将非常接近于完全由我自己来实现。
    但是,要优化所有这些,我需要花费很多时间。

    听起来,您试图做的事情在某些方面与您的类似

    图只是从关键字到关键字函数的映射。在这种情况下,统计图表示获取数字序列(xs)并生成这些数字的单变量统计(即,平均值m和方差v)的步骤。每个fnk的参数名称可以引用在执行步骤之前必须执行的其他步骤。例如,在上面的示例中,要执行:v,必须首先执行:m和:m2步骤(分别为均方和均方)


    听起来你正在尝试做的事情在某些方面与你的相似

    图只是从关键字到关键字函数的映射。在这种情况下,统计图表示获取数字序列(xs)并生成这些数字的单变量统计(即,平均值m和方差v)的步骤。每个fnk的参数名称可以引用在执行步骤之前必须执行的其他步骤。例如,在上面的示例中,要执行:v,必须首先执行:m和:m2步骤(分别为均方和均方)


    据我所知,您希望找到一个图中从输入节点到输出节点的所有路径,其中图中的每个节点都是某个值,每个连接都是函数应用程序,并将它们组成一棵树

    以下是一些粗略(部分)的解决方案:

    假设我们想得到一个算术运算的列表,将一个数字与另一个数字进行比较。我们有函数描述:适用函数的谓词对集合。谓词检查,如果相应的函数适用于某些输入:

    (def fns
      [[zero? {:add3 #(+ 3 %)}]
       [#(== % 1) {:add2 #(+ 2 %) :sub10 #(- 10 %)}]
       [even? {:mul3 #(* 3 %) :add2 #(+ 2 %) :add1 inc}]
       [#(> % 50) {:sub49 #(- % 49)}]
       [(constantly true) {:add1 inc}]])
    
    (defn applicable-fns [fns input]
      (some (fn [[pred f-map]]
              (when (pred input)
                f-map))
            fns))
    
    答复:

    (applicable-fns fns 1)
    
    ;; {:add2 #function[reactive-clj.core/fn--21334], 
        :sub10 #function[reactive-clj.core/fn--21336]}
    
    由于我们无法查看所有的数字,我们只需将我们的域限制在-100到100之间:

    (defn in-domain? [i] (<= -100 i 100))
    
    这是一个简单的(更容易理解)