1. 逻辑编程思维:
逻辑编程(逻辑程序设计)是种编程范型,它设置答案须匹配的规则来解决问题,而非设置步骤来解决问题。过程是:
(run* [logic-variable]
logic-expressions)
;;or
(run n [logic-variable]
logic-expressions)
run或者run函数可以执行逻辑表达式,返回满足条件的结果。返回的结果是一个关于logic-variable的数组。如果是run则返回所有满足逻辑表达式条件的逻辑变量,如果是run n,则返回前n个满足条件的变量。这里要注意的一点是:普通的逻辑表达式的返回结果只有两种:succeed/fail,如果找到满足条件的结果,则返回succeed,否则返回fail。只有使用run函数才能返回最终我们想要的输出结果。下面是run函数的使用示例:
;;首先要导入clojure.core.logic库
(use 'clojure.core.logic)
;;使用run*,会返回所有满足条件的结果
(run* [q]
;;这里是逻辑表达式,后面会讲到
(conde
[(== q 1)]
[(== q 2)]
[(== q 3)]
))
;;=>(1 2 3)
;;返回前两个结果
(run 2 [q]
(conde
[(== q 1)]
[(== q 2)]
[(== q 3)]
))
;;=> (1 2)
;;如果n大于所有满足条件结果的总数,则与run*返回结果一致
(run 4 [q]
(conde
[(== q 1)]
[(== q 2)]
[(== q 3)]
))
;;=> (1 2 3)
当然run函数也可以接收多个参数,如果是多个参数,则以数组的形式返回:
;;接收两个参数,最后返回结果是一个包含数组的序列
(run* [q1 q2]
(== q1 1)
(== q2 1)
)
;;=> ([1 1])
####3. 逻辑表达式以及常用函数:
逻辑表达式的返回结果都是succeed或者fail,一个逻辑表达式中可以继续嵌套另外一个逻辑表达式,下面在介绍clojure中的常用逻辑函数同时穿插的介绍如何使用逻辑编程:
#####(1)==/!=/membero函数:
“==”/"!="函数用于判断两个逻辑变量是否相等或者不相等,是最常用的逻辑函数,而(membero x l)函数则表示只有x属于数组l时才会返回succeed:
;;找出等于1的数字
(run* [q] (== q 1))
;;=> (1)
;;找出不等于1且属于数组[1 2 3]中的数字
;;;;这里的(!= q 1)与(membero q [1 2 3])两个逻辑表达式是与的关系(也就是必须两个逻辑表达式同时满足才返回succeed)
(run* [q]
(!= q 1)
;;q只有是数组[1 2 3]中的一个元素,才会返回succeed
(membero q [1 2 3]))
;;=> (2 3)
#####(2)fresh函数:
这个函数在逻辑编程时特别重要,如果我们想在逻辑表达式中用到其他变量怎么办?怎么像其它语言一样去声明一个局部变量??fresh函数正是来解决以上疑问的,fresh函数可以声明几个局部的逻辑变量,有了这些局部逻辑变量以后,您就可以在逻辑表达式中随意发挥了: