(use 'clojure.core.logic)
Jonas Enlund
Helsinki, April 2013
$ lein kibit src/overtone/examples/compositions/jazz.clj
$ lein kibit src/overtone/examples/compositions/jazz.clj
At src/overtone/examples/compositions/jazz.clj:100:
Consider using:
(if-not (zero? (mod beat 2))
(dec n)
(limit (+ n (rand-nth jazz-intervals)) maxbass minbass))
instead of:
(if (not (zero? (mod beat 2)))
(dec n)
(limit (+ n (rand-nth jazz-intervals)) maxbass minbass))
$ lein kibit src/overtone/examples/compositions/jazz.clj
At src/overtone/examples/compositions/jazz.clj:100:
Consider using:
(if-not (zero? (mod beat 2))
(dec n)
(limit (+ n (rand-nth jazz-intervals)) maxbass minbass))
instead of:
(if (not (zero? (mod beat 2)))
(dec n)
(limit (+ n (rand-nth jazz-intervals)) maxbass minbass))
At src/overtone/examples/compositions/jazz.clj:114:
Consider using:
(inc beat)
instead of:
(+ beat 1)
$ lein kibit src/overtone/examples/compositions/jazz.clj
At src/overtone/examples/compositions/jazz.clj:100:
Consider using:
(if-not (zero? (mod beat 2))
(dec n)
(limit (+ n (rand-nth jazz-intervals)) maxbass minbass))
instead of:
(if (not (zero? (mod beat 2)))
(dec n)
(limit (+ n (rand-nth jazz-intervals)) maxbass minbass))
At src/overtone/examples/compositions/jazz.clj:114:
Consider using:
(inc beat)
instead of:
(+ beat 1)
At src/overtone/examples/compositions/jazz.clj:133:
Consider using:
(let [start (+ 1 (metro))]
(at (metro start) (rotater-on note vel))
(apply-by (metro (+ len start)) #'rotater-off [note]))
instead of:
(let [start (+ 1 (metro))]
(do
(at (metro start) (rotater-on note vel))
(apply-by (metro (+ len start)) #'rotater-off [note])))
(defrules rules
[(if (not ?pred) ?then ?else) (if-not ?pred ?then ?else)]
[(+ ?x 1) (inc ?x)]
[(let ?binding (do . ?body)) (let ?binding . ?body)]
;; etc ...
)
(no prior knowledge of core.logic
required)
(run* [q]
(== 42 q))
(run* [q]
(== 42 q))
;; (42)
(run* [q]
(== 42 q))
;; (42)
(run* [q]
(== q '(+ 42 1)))
(run* [q]
(== 42 q))
;; (42)
(run* [q]
(== q '(+ 42 1)))
;; ((+ 42 1))
(run* [q]
(== 42 q))
;; (42)
(run* [q]
(== q '(+ 42 1)))
;; ((+ 42 1))
(run* [q]
(== `(+ ~q 1)
`(+ 42 1)))
(run* [q]
(== 42 q))
;; (42)
(run* [q]
(== q '(+ 42 1)))
;; ((+ 42 1))
(run* [q]
(== `(+ ~q 1)
`(+ 42 1)))
;; (42)
(run* [q]
(== 42 q))
;; (42)
(run* [q]
(== q '(+ 42 1)))
;; ((+ 42 1))
(run* [q]
(== `(+ ~q 1)
`(+ 42 1)))
;; (42)
(run* [q]
(fresh [x]
(== `(+ ~x 1)
`(+ 42 1))
(== `(inc ~x) q)))
(run* [q]
(== 42 q))
;; (42)
(run* [q]
(== q '(+ 42 1)))
;; ((+ 42 1))
(run* [q]
(== `(+ ~q 1)
`(+ 42 1)))
;; (42)
(run* [q]
(fresh [x]
(== `(+ ~x 1)
`(+ 42 1))
(== `(inc ~x) q)))
;; ((clojure.core/inc 42))
(inc-rule <form>)
(inc-rule <form>)
(defn inc-rule [form]
(run* [q]
(fresh [x]
(== `(+ ~x 1) form)
(== `(inc ~x) q))))
(inc-rule <form>)
(defn inc-rule [form]
(run* [q]
(fresh [x]
(== `(+ ~x 1) form)
(== `(inc ~x) q))))
(inc-rule `(+ 42 1))
(inc-rule <form>)
(defn inc-rule [form]
(run* [q]
(fresh [x]
(== `(+ ~x 1) form)
(== `(inc ~x) q))))
(inc-rule `(+ 42 1))
;; ((clojure.core/inc 42))
(inc-rule <form>)
(defn inc-rule [form]
(run* [q]
(fresh [x]
(== `(+ ~x 1) form)
(== `(inc ~x) q))))
(inc-rule `(+ 42 1))
;; ((clojure.core/inc 42))
(inc-rule `(map inc [1 2 3]))
(inc-rule <form>)
(defn inc-rule [form]
(run* [q]
(fresh [x]
(== `(+ ~x 1) form)
(== `(inc ~x) q))))
(inc-rule `(+ 42 1))
;; ((clojure.core/inc 42))
(inc-rule `(map inc [1 2 3]))
;; ()
((rule [<pattern> <subst>]) <form>)
((rule [<pattern> <subst>]) <form>)
(defn rule [[patt subst]]
(fn [form]
(run* [q]
(== patt form)
(== subst q))))
((rule [<pattern> <subst>]) <form>)
(defn rule [[patt subst]]
(fn [form]
(run* [q]
(== patt form)
(== subst q))))
((rule [`(+ ~(lvar 'x false) 1)
`(inc ~(lvar 'x false))])
`(+ 42 1))
((rule [<pattern> <subst>]) <form>)
(defn rule [[patt subst]]
(fn [form]
(run* [q]
(== patt form)
(== subst q))))
((rule [`(+ ~(lvar 'x false) 1)
`(inc ~(lvar 'x false))])
`(+ 42 1))
;; ((clojure.core/inc 42))
((rule [<pattern> <subst>]) <form>)
(defn rule [[patt subst]]
(fn [form]
(run* [q]
(== patt form)
(== subst q))))
((rule [`(+ ~(lvar 'x false) 1)
`(inc ~(lvar 'x false))])
`(+ 42 1))
;; ((clojure.core/inc 42))
(let [coll (lvar 'coll false)
keys (lvar 'keys false)
val (lvar 'val false)
update-in-rule (rule [`(update-in ~coll ~keys assoc ~val)
`(assoc-in ~coll ~keys ~val)])
form `(update-in {:x {:y 0}} [:x :z] assoc 0)]
(update-in-rule form))
((rule [<pattern> <subst>]) <form>)
(defn rule [[patt subst]]
(fn [form]
(run* [q]
(== patt form)
(== subst q))))
((rule [`(+ ~(lvar 'x false) 1)
`(inc ~(lvar 'x false))])
`(+ 42 1))
;; ((clojure.core/inc 42))
(let [coll (lvar 'coll false)
keys (lvar 'keys false)
val (lvar 'val false)
update-in-rule (rule [`(update-in ~coll ~keys assoc ~val)
`(assoc-in ~coll ~keys ~val)])
form `(update-in {:x {:y 0}} [:x :z] assoc 0)]
(update-in-rule form))
;; ((clojure.core/assoc-in {:x {:y 0}} [:x :z] 0))
(defn prepare [form]
(walk/prewalk
#(if (and (symbol? %)
(.startsWith (name %) "?"))
(lvar % false)
%)
form))
(defn prepare [form]
(walk/prewalk
#(if (and (symbol? %)
(.startsWith (name %) "?"))
(lvar % false)
%)
form))
(prepare '[(+ ?x 1) (inc ?x)])
(defn prepare [form]
(walk/prewalk
#(if (and (symbol? %)
(.startsWith (name %) "?"))
(lvar % false)
%)
form))
(prepare '[(+ ?x 1) (inc ?x)])
;; [(+ <lvar:?x> 1) (inc <lvar:?x>)]
(defn prepare [form]
(walk/prewalk
#(if (and (symbol? %)
(.startsWith (name %) "?"))
(lvar % false)
%)
form))
(prepare '[(+ ?x 1) (inc ?x)])
;; [(+ <lvar:?x> 1) (inc <lvar:?x>)]
((rule (prepare '[(+ ?x 1) (inc ?x)]))
'(+ x 1))
(defn prepare [form]
(walk/prewalk
#(if (and (symbol? %)
(.startsWith (name %) "?"))
(lvar % false)
%)
form))
(prepare '[(+ ?x 1) (inc ?x)])
;; [(+ <lvar:?x> 1) (inc <lvar:?x>)]
((rule (prepare '[(+ ?x 1) (inc ?x)]))
'(+ x 1))
;; ((inc x))
(defn prepare [form]
(walk/prewalk
#(if (and (symbol? %)
(.startsWith (name %) "?"))
(lvar % false)
%)
form))
(prepare '[(+ ?x 1) (inc ?x)])
;; [(+ <lvar:?x> 1) (inc <lvar:?x>)]
((rule (prepare '[(+ ?x 1) (inc ?x)]))
'(+ x 1))
;; ((inc x))
((rule (prepare '[(update-in ?coll ?keys assoc ?val)
(assoc-in ?coll ?keys ?val)]))
'(update-in coll [:x :y] assoc 42))
(defn prepare [form]
(walk/prewalk
#(if (and (symbol? %)
(.startsWith (name %) "?"))
(lvar % false)
%)
form))
(prepare '[(+ ?x 1) (inc ?x)])
;; [(+ <lvar:?x> 1) (inc <lvar:?x>)]
((rule (prepare '[(+ ?x 1) (inc ?x)]))
'(+ x 1))
;; ((inc x))
((rule (prepare '[(update-in ?coll ?keys assoc ?val)
(assoc-in ?coll ?keys ?val)]))
'(update-in coll [:x :y] assoc 42))
;; ((assoc-in coll [:x :y] 42))
(defn rule [r]
(let [r (prepare r)]
(fn [form]
(run* [q]
(fresh [patt subst]
(== [patt subst] r)
(== patt form)
(== [form subst] q))))))
(defn rule [r]
(let [r (prepare r)]
(fn [form]
(run* [q]
(fresh [patt subst]
(== [patt subst] r)
(== patt form)
(== [form subst] q))))))
((rule '[(+ ?x 1) (inc ?x)])
'(+ 42 1))
(defn rule [r]
(let [r (prepare r)]
(fn [form]
(run* [q]
(fresh [patt subst]
(== [patt subst] r)
(== patt form)
(== [form subst] q))))))
((rule '[(+ ?x 1) (inc ?x)])
'(+ 42 1))
;; ([(+ 42 1) (inc 42)])
(run* [q]
(membero q [1 2 3 4]))
(run* [q]
(membero q [1 2 3 4]))
;; (1 2 3 4)
(run* [q]
(membero q [1 2 3 4]))
;; (1 2 3 4)
(run* [q]
(membero 2 [1 q 3 4]))
(run* [q]
(membero q [1 2 3 4]))
;; (1 2 3 4)
(run* [q]
(membero 2 [1 q 3 4]))
;; (2)
(run* [q]
(membero q [1 2 3 4]))
;; (1 2 3 4)
(run* [q]
(membero 2 [1 q 3 4]))
;; (2)
(run* [q]
(fresh [x y]
(== x y)
(membero x [1 2 3 4])
(membero y [3 4 5 6])
(== q [x y])))
(run* [q]
(membero q [1 2 3 4]))
;; (1 2 3 4)
(run* [q]
(membero 2 [1 q 3 4]))
;; (2)
(run* [q]
(fresh [x y]
(== x y)
(membero x [1 2 3 4])
(membero y [3 4 5 6])
(== q [x y])))
;; ([3 3] [4 4])
(defn rules [rs]
(let [rs (map prepare rs)]
(fn [form]
(run* [q]
(fresh [patt subst]
(membero [patt subst] rs)
(== patt form)
(== [form subst] q))))))
(defn rules [rs]
(let [rs (map prepare rs)]
(fn [form]
(run* [q]
(fresh [patt subst]
(membero [patt subst] rs)
(== patt form)
(== [form subst] q))))))
(defmacro defrules
[name & rs]
`(def ~name
(rules (quote ~rs))))
(defn rules [rs]
(let [rs (map prepare rs)]
(fn [form]
(run* [q]
(fresh [patt subst]
(membero [patt subst] rs)
(== patt form)
(== [form subst] q))))))
(defmacro defrules
[name & rs]
`(def ~name
(rules (quote ~rs))))
(defrules my-rules
[(+ ?x 1) (inc ?x)]
[(- ?x 1) (dec ?x)]
[(< 0 ?x) (pos? ?x)]
[(< ?x 0) (neg? ?x)]
[(if ?test ?else nil) (when ?test ?else)]
[(into [] ?coll) (vec ?coll)]
[(apply concat (map ?f ?xs)) (mapcat ?f ?xs)])
(my-rules '(if (some f xs) f nil))
(my-rules '(if (some f xs) f nil))
;; ([(if (some f xs) f nil) (when (some f xs) f)])
(my-rules '(if (some f xs) f nil))
;; ([(if (some f xs) f nil) (when (some f xs) f)])
(my-rules '(fn [x]
(if (< x 0)
(+ x 1)
nil)))
(my-rules '(if (some f xs) f nil))
;; ([(if (some f xs) f nil) (when (some f xs) f)])
(my-rules '(fn [x]
(if (< x 0)
(+ x 1)
nil)))
;; ()
(tree-seq sequential? seq '(map (fn [x y] (+ x y)) xs))
(tree-seq sequential? seq '(map (fn [x y] (+ x y)) xs))
;; ((map (fn [x y] (+ x y)) xs),
;; map, (fn [x y] (+ x y)), fn,
;; [x y], x, y, (+ x y), +, x
;; y, xs)
(tree-seq sequential? seq '(map (fn [x y] (+ x y)) xs))
;; ((map (fn [x y] (+ x y)) xs),
;; map, (fn [x y] (+ x y)), fn,
;; [x y], x, y, (+ x y), +, x
;; y, xs)
(defn rules [rs]
(let [rs (map prepare rs)]
(fn [form]
(run* [q]
(fresh [patt subst subform]
(membero [patt subst] rs)
(membero subform (tree-seq sequential? seq form))
(== patt subform)
(== [subform subst] q))))))
(tree-seq sequential? seq '(map (fn [x y] (+ x y)) xs))
;; ((map (fn [x y] (+ x y)) xs),
;; map, (fn [x y] (+ x y)), fn,
;; [x y], x, y, (+ x y), +, x
;; y, xs)
(defn rules [rs]
(let [rs (map prepare rs)]
(fn [form]
(run* [q]
(fresh [patt subst subform]
(membero [patt subst] rs)
(membero subform (tree-seq sequential? seq form))
(== patt subform)
(== [subform subst] q))))))
(my-rules '(fn [x]
(if (< x 0)
(+ x 1)
nil))
(tree-seq sequential? seq '(map (fn [x y] (+ x y)) xs))
;; ((map (fn [x y] (+ x y)) xs),
;; map, (fn [x y] (+ x y)), fn,
;; [x y], x, y, (+ x y), +, x
;; y, xs)
(defn rules [rs]
(let [rs (map prepare rs)]
(fn [form]
(run* [q]
(fresh [patt subst subform]
(membero [patt subst] rs)
(membero subform (tree-seq sequential? seq form))
(== patt subform)
(== [subform subst] q))))))
(my-rules '(fn [x]
(if (< x 0)
(+ x 1)
nil))
;; ([(+ x 1) (inc x)]
;; [(< x 0) (neg? x)]
;; [(if (< x 0) (+ x 1) nil) (when (< x 0) (+ x 1))])
(defn simplify* [form rules-fn]
(walk/prewalk-replace (into {} (rules-fn form))
form))
(defn simplify* [form rules-fn]
(walk/prewalk-replace (into {} (rules-fn form))
form))
(simplify* '(fn [x]
(if (< x 0)
(+ x 1)
nil))
my-rules)
(defn simplify* [form rules-fn]
(walk/prewalk-replace (into {} (rules-fn form))
form))
(simplify* '(fn [x]
(if (< x 0)
(+ x 1)
nil))
my-rules)
;; (fn [x]
;; (when (neg? x)
;; (inc x)))
(defn simplify* [form rules-fn]
(walk/prewalk-replace (into {} (rules-fn form))
form))
(simplify* '(defn my-fun [xs]
(apply concat
(map (fn [x]
(into [] (if (< x 0)
[(- x 1) (+ x 1)]
nil)))
xs)))
my-rules)
(defn simplify* [form rules-fn]
(walk/prewalk-replace (into {} (rules-fn form))
form))
(simplify* '(defn my-fun [xs]
(apply concat
(map (fn [x]
(into [] (if (< x 0)
[(- x 1) (+ x 1)]
nil)))
xs)))
my-rules)
;; (defn my-fun [xs]
;; (mapcat (fn [x]
;; (vec (when (neg? x)
;; [(dec x) (inc x)])))
;; xs))
(defrules max-rule
[(max z ?x) ?x]
[(max ?x z) ?x]
[(max (s ?x) (s ?y)) (s (max ?x ?y))])
(defrules max-rule
[(max z ?x) ?x]
[(max ?x z) ?x]
[(max (s ?x) (s ?y)) (s (max ?x ?y))])
(simplify* '(max (s (s (s z)))
(s (s (s (s (s z))))))
max-rule)
(defrules max-rule
[(max z ?x) ?x]
[(max ?x z) ?x]
[(max (s ?x) (s ?y)) (s (max ?x ?y))])
(simplify* '(max (s (s (s z)))
(s (s (s (s (s z))))))
max-rule)
;; (s (max (s (s z))
;; (s (s (s (s z))))))
(defrules max-rule
[(max z ?x) ?x]
[(max ?x z) ?x]
[(max (s ?x) (s ?y)) (s (max ?x ?y))])
(simplify* '(max (s (s (s z)))
(s (s (s (s (s z))))))
max-rule)
;; (s (max (s (s z))
;; (s (s (s (s z))))))
(defn simplify [form rules-fn]
(loop [form form]
(let [new-form (simplify* form rules-fn)]
(if (= new-form form)
form
(recur form)))))
(defrules max-rule
[(max z ?x) ?x]
[(max ?x z) ?x]
[(max (s ?x) (s ?y)) (s (max ?x ?y))])
(simplify* '(max (s (s (s z)))
(s (s (s (s (s z))))))
max-rule)
;; (s (max (s (s z))
;; (s (s (s (s z))))))
(defn simplify [form rules-fn]
(loop [form form]
(let [new-form (simplify* form rules-fn)]
(if (= new-form form)
form
(recur form)))))
(simplify '(max (s (s (s z)))
(s (s (s (s (s z))))))
max-rule)
(defrules max-rule
[(max z ?x) ?x]
[(max ?x z) ?x]
[(max (s ?x) (s ?y)) (s (max ?x ?y))])
(simplify* '(max (s (s (s z)))
(s (s (s (s (s z))))))
max-rule)
;; (s (max (s (s z))
;; (s (s (s (s z))))))
(defn simplify [form rules-fn]
(loop [form form]
(let [new-form (simplify* form rules-fn)]
(if (= new-form form)
form
(recur form)))))
(simplify '(max (s (s (s z)))
(s (s (s (s (s z))))))
max-rule)
;; (s (s (s (s (s z)))))
(defrules insertion-sort
[(max z ?x) ?x]
[(max ?x z) ?x]
[(max (s ?x) (s ?y)) (s (max ?x ?y))]
[(min z ?x) z]
[(min ?x z) z]
[(min (s ?x) (s ?y)) (s (min ?x ?y))]
[(sort nil) nil]
[(sort (cons ?x ?y)) (insert ?x (sort ?y))]
[(insert ?x nil) (cons ?x nil)]
[(insert ?x (cons ?y ?z)) (cons (min ?x ?y) (insert (max ?x ?y) ?z))])
(defrules insertion-sort
[(max z ?x) ?x]
[(max ?x z) ?x]
[(max (s ?x) (s ?y)) (s (max ?x ?y))]
[(min z ?x) z]
[(min ?x z) z]
[(min (s ?x) (s ?y)) (s (min ?x ?y))]
[(sort nil) nil]
[(sort (cons ?x ?y)) (insert ?x (sort ?y))]
[(insert ?x nil) (cons ?x nil)]
[(insert ?x (cons ?y ?z)) (cons (min ?x ?y) (insert (max ?x ?y) ?z))])
(simplify '(sort (cons (s (s z))
(cons (s z)
(cons (s (s (s z)))
(cons z nil)))))
insertion-sort)
(defrules insertion-sort
[(max z ?x) ?x]
[(max ?x z) ?x]
[(max (s ?x) (s ?y)) (s (max ?x ?y))]
[(min z ?x) z]
[(min ?x z) z]
[(min (s ?x) (s ?y)) (s (min ?x ?y))]
[(sort nil) nil]
[(sort (cons ?x ?y)) (insert ?x (sort ?y))]
[(insert ?x nil) (cons ?x nil)]
[(insert ?x (cons ?y ?z)) (cons (min ?x ?y) (insert (max ?x ?y) ?z))])
(simplify '(sort (cons (s (s z))
(cons (s z)
(cons (s (s (s z)))
(cons z nil)))))
insertion-sort)
;; (cons z
;; (cons (s z)
;; (cons (s (s z))
;; (cons (s (s (s z)))
;; nil))))
code: https://github.com/jonase/kibit-demo
slides: http://jonase.github.io/kibit-demo
More about term rewriting systems (TRS):
Keyboard shortcuts
↑, ←, pg up, k | Go to previous slide |
↓, →, pg dn, space, j | Go to next slide |
home / end | Go to first / last slide |
? | Show help |
esc | Back to slideshow |