【问题标题】:clojure core.logic counting elements in a setclojure core.logic 计数集合中的元素
【发布时间】:2013-09-26 03:05:56
【问题描述】:

我尝试在 core.logic 中做这样的事情

(defn count-different-elements-in-list [coll]
  (count (set coll)))

这适用于整数就好了

(should= 1 (count-different-elements-in-list '(1 1 1)))
(should= 2 (count-different-elements-in-list '(1 1 2)))
(should= 3 (count-different-elements-in-list '(1 3 2)))

但现在我正在尝试使用 core.logic 来解决一些问题,结果变得一团糟

(run* [a b c]
  ;;the variables get values between 1 and 3
  (fd/in a b c (fd/interval 1 3))
  ;; in the list there should only be 2 different values
  (== 2 (count-different-elements-in-list '(a b c))))

但是问题来了,a b c 没有作为值传递给函数。它们作为变量传递。使用三个变量 count-different-elements-in-list 总是返回 3 并且 core.logic 找不到解决方案(空列表)。

但我正在寻找这个结果。

([1 1 2] [1 2 1] [2 1 1] 
 [1 1 3] [1 3 1] [3 1 1]
 [2 2 1] [2 1 2] [1 2 2]
 [2 2 3] [2 3 2] [3 2 2]
 [3 3 1] [3 1 3] [1 3 3]
 [3 3 2] [3 2 3] [2 3 3])

【问题讨论】:

    标签: clojure clojure-core.logic


    【解决方案1】:

    您需要将core.logic/project 逻辑变量转换为非关系目标,如普通函数count-different-elements-in-list。不幸的是,您不能project 有限域逻辑变量,如abc,它们不限于单个值。 (见:this question

    在您的示例中,您可以将fd/infd/interval 换成生成的范围和membero。这将删除无约束的有限域变量,保留整数的范围约束,并允许投影。

    (def interval (vec (range 1 4)))
    (run* [a b c]
      (membero a interval)
      (membero b interval)
      (membero c interval)
      (project [a b c]
        (== 2 (count-different-elements-in-list (list a b c)))))
    

    【讨论】:

    • 没有得到它,但是通过在结果上应用 count-different-elements-in-list 函数解决了这个问题。学习 clojure 需要时间。
    • 约束中使用的普通函数,如count-different-elements-in-list,在 core.logic 中被视为非关系目标。我已经达到了我目前的知识水平,所以我实际上无法解释它。
    • 再举个例子。它有助于为您解决问题吗?
    • 我不会说count-different-elements-in-list 是一个非关系性目标。这根本不是目标。它只是一个 clojure 函数,这就是为什么你需要投影你的 lvar 来与之交互的原因。
    猜你喜欢
    • 1970-01-01
    • 2015-08-14
    • 2012-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多