Doc updates

This commit is contained in:
Paul deGrandis 2012-03-09 11:06:44 -05:00
parent 3f20f320c9
commit 6b6822a749
2 changed files with 63 additions and 43 deletions

View file

@ -17,31 +17,29 @@
;; For more information, see: [rule](#jonase.kibit.rules) namespace ;; For more information, see: [rule](#jonase.kibit.rules) namespace
(def all-rules core-rules/all-rules) (def all-rules core-rules/all-rules)
;; Unification ;; Building an alternative form
;; ----------- ;; ----------------------------
;; ;;
;; `unify` takes an expression and a `rule`. A rule is a pair ;; ### Unification
;; consisting of ;; `unify` takes an expression and a `rule` pair (pattern and substitution).
;; For more information on rule pairs,
;; see: [rules](#jonase.kibit.rules) namespace
;; ;;
;; * a pattern expression (e.g. `(+ ?x 1)`) ;; If the expression-under-analysis matches the pattern, the substitution
;; * a substitution expression (e.g. `(inc ?x)` ;; expression is used to build an alternative expression. For example,
;; ;; given the expression `(+ (f x) 1)` and the rule `[(+ ?x 1) (inc ?x)]`,
;; If the pattern matches the expression the substitution expression ;; the expression `(inc (f x))` is built. This is all handled by `core.logic`.
;; is used to build an alternative expression. For example, given the
;; expression `(+ (f x) 1)` and the rule `[(+ ?x 1) (inc ?x)]`, the ;; TODO run*, ==, and why `first` needs to be called
;; expression `(inc (f x))` is built. This is all handled by
;; `core.logic`.
;; ;;
;; Finally, if unification succeeds, a map containing the original ;; Finally, if unification succeeds, a map containing the original
;; expression (`:expr`), the line where it appeared in the source file ;; expression (`:expr`), the line where it appeared in the source file
;; (`:line`), the rule which was used (`rule`) and the suggested ;; (`:line`), the rule which was used (`:rule`) and the suggested
;; alternative built by `core.logic` (`:alt`) is returned. If the ;; alternative built by `core.logic` (`:alt`) is returned. If the
;; unification failed `nil` is returned. ;; unification failed `nil` is returned.
(defn unify (defn unify
"Attempts to unify expr with rule. On success a map is returned "Unify expr with a rule pair. On success, return a map keyed with
containing :rule, :expression, :line and :alt (suggested `:rule, :expr, :line and :alt`, otherwise return `nil`"
alternative) keys. Returns nil if unification fails"
[expr rule] [expr rule]
(let [[r s] (#'logic/prep rule) (let [[r s] (#'logic/prep rule)
alt (first (logic/run* [alt] alt (first (logic/run* [alt]
@ -55,6 +53,8 @@
alt) alt)
:line (-> expr meta :line)}))) :line (-> expr meta :line)})))
;; ### Applying unification
;; The `check-form` function does a linear search over the rules and ;; The `check-form` function does a linear search over the rules and
;; returns the map created by the first successful unification with ;; returns the map created by the first successful unification with
;; expr. ;; expr.
@ -67,12 +67,12 @@
(when (sequential? expr) (when (sequential? expr)
(some #(unify expr %) rules)))) (some #(unify expr %) rules))))
;; This walks across all the forms within a seq'd form/expression, ;; This walks across all the forms within an expr-sequence,
;; checking each inner form. We have to restore `:expr` because it ;; checking each inner form. We have to restore `:expr` because it
;; gets munged in the tree/expr walk ;; gets munged in the tree/expr walk
(defn check-expr (defn check-expr
"Given a full expression/form-of-forms/form, a map containing the "Given a full expression/form-of-forms/form, return a map containing the
alternative suggestion info, or `nil`" alternative suggestion info, or `nil` (see: `check-form`)"
[expr] [expr]
(if-let [new-expr (walk/walk #(or (-> % check-form :alt) %) check-form expr)] (if-let [new-expr (walk/walk #(or (-> % check-form :alt) %) check-form expr)]
(assoc new-expr :expr expr) (assoc new-expr :expr expr)
@ -80,10 +80,10 @@
;; Reading source files ;; Reading source files
;; -------------------- ;; --------------------
;;
;; `read-ns` reads a Clojure source file and returns a sequence of the ;; `read-ns` is intended to be used with a Clojure source file,
;; top level forms. Line numbers are added as `:line` metadata to the ;; but will work for anything wrapped in a LinNumberingPushbackReader.
;; forms. ;; Line numbers are added as `:line` metadata to the forms.
(defn read-ns (defn read-ns
"Generate a lazy sequence of top level forms from a "Generate a lazy sequence of top level forms from a
LineNumberingPushbackReader" LineNumberingPushbackReader"
@ -94,9 +94,9 @@
(when-not (= form ::eof) (when-not (= form ::eof)
(cons (with-meta form {:line line-num}) (read-ns r)))))) (cons (with-meta form {:line line-num}) (read-ns r))))))
;; `Expr-seq` takes an expression and returns a lazy sequence of the ;; `tree-seq` returns a lazy-seq of nodes for a tree.
;; expression itself and all its sub-expressions in a depth-first ;; Given an expression, we can then match rules against its pieces.
;; manner: ;; This is like using `clojure.walk` with `identity`:
;; ;;
;; user=> (expr-seq '(if (pred? x) (inc x) x)) ;; user=> (expr-seq '(if (pred? x) (inc x) x))
;; ((if (pred? x) (inc x) x) ;; ((if (pred? x) (inc x) x)
@ -107,9 +107,10 @@
;; (inc x) ;; (inc x)
;; inc ;; inc
;; x ;; x
;; x) ;; x)`
;;
(defn expr-seq (defn expr-seq
"Returns a lazy (depth-first) sequence of expr and all its "Given an expreesion seq, return a lazy (depth-first) sequence of expr and all its
sub-expressions" sub-expressions"
[expr] [expr]
(tree-seq sequential? (tree-seq sequential?

View file

@ -1,12 +1,31 @@
(ns jonase.kibit.rules (ns jonase.kibit.rules
"`rules.clj` provides the core functionality for extracting "`rules.clj` provides the core functionality for extracting
and merging rules from namespaces. There are shorthand `def`s and merging rules from namespaces. There are shorthands for
for rule the core rule sets" the individual rule sets, via the `rule-map`"
(:require [jonase.kibit.rules.arithmetic :as arith] (:require [jonase.kibit.rules.arithmetic :as arith]
[jonase.kibit.rules.control-structures :as control] [jonase.kibit.rules.control-structures :as control]
[jonase.kibit.rules.misc :as misc])) [jonase.kibit.rules.misc :as misc]))
(def rule-map {:control-structures control/rules ;; More information on rules
;; -------------------------
;;
;; Rule sets are stored in individual files that have a top level
;; `(def rules '{...})`. The collection of rules are in the `rules`
;; directory.
;;
;; Each rule (also called a rule pair) in a rule set map is comprised of:
;;
;; * a pattern expression (e.g. `(+ ?x 1)`)
;; * a substitution expression (e.g. `(inc ?x)`
;;
;; These rules are used in the unifcation process to generate suggested
;; code alternatives. For more information see:
;; [core](#jonase.kibit.core) namespace
(def "A map of the individual rule sets, keyed by rule group"
rule-map {:control-structures control/rules
:arithmetic arith/rules :arithmetic arith/rules
:misc misc/rules}) :misc misc/rules})