Doc updates
This commit is contained in:
parent
3f20f320c9
commit
6b6822a749
2 changed files with 63 additions and 43 deletions
|
@ -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?
|
||||||
|
|
|
@ -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})
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue