Open Vaguery opened 5 years ago
Update: If I use the keyword :k
there's no problem getting my rules to fire, but there are difficulties afterward.
Is the trick here that I should not be using a var
for my "special variable"?
My goal here is to permit a simplification of something like (* (+ x x) (+ k k))
to (eventually) (* k x)
, using rewrite rules something like:
(+ x x) -> (* 2 x)
(+ k k) -> k
(* (* 2 x) k) -> (* 2 x k) -> (* k x)
(and so on).
When I use a keyword, my specially-defined rules for :k
work under transform-expression
, but the standard arithmetic simplification fails on the keyword. When I use a symbol k
, the standard arithmetic simplification rules are applied to the non-standard symbol k
as if it were a variable name.
Any advice would be welcomed.
As I try things, a few more (of my) mistakes become apparent and I seem to be better able to say what I'm looking for:
What I want to be able to do is (1) standard arithmetic simplification, but (2) using a special set of domain-specific additional rules for a particular symbol, keyword, or function.
When I use a symbol for the special thing ('k
), the standard arithmetic simplification rules do things I don't want to have happen, like (/ k k) :=> 1.0
. That is not true, for this definition of 'k
as a late-binding random variable.
When I use a keyword for the special thing (:k
), the standard arithmetic simplification rules die when I apply them to anything like (+ x :k)
.
When I use a function for the special thing, like this:
(declare erc)
(defn k [] (erc))
(def k-mul (rule (ex (* (k) (k) ?&*)) :=> '(* (k) ?&*)))
The code doesn't compile.
The closest I seem to be able to come, so far, is to copy all of the algebraic simplification rules from the core library, and add a guard clause like (not= ?x k)
as much as I can....
The use case is relatively simple:
The arithmetic expressions I'm working with have a
k
symbol in them (an "ephemeral random constant"), which is interpreted as "some number, which is almost certainly different in each case".So for example, in a simple-sounding scheme where
k
just appears like a variable name in an expression, I would want to override expresso's simplification dynamics so that(/ k k)
does not get simplified to1.0
, but instead is reduced tok
. The same applies to almost any arithmetic function;(+ k k) :=> k
, for example, and so on.I've tried an awful lot of different variations on the rule definition of
erc-mult
, and none of them seem to recognize a pattern like(+ k k)
, regardless of number of matchers, serial matchers, quotes, all kinds of stuff. The same kind of pattern will definitely recognize(+ 88 88)
if I define it to handle an explicit number, it just won't managek
as far as I can tell.Is there something I've missed in defining a rule on an abstract symbol like this? I feel as though I've been over all the docs in detail, but I just can't seem to get through this blockage.