Skip to content

Having trouble building a rule #32

Description

@Vaguery

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 to 1.0, but instead is reduced to k. The same applies to almost any arithmetic function; (+ k k) :=> k, for example, and so on.

(ns hashed-symbolic-regression.core-test
  (:require 
            [numeric.expresso.core :as ex]
            [numeric.expresso.rules :as er]
            ))

(declare k) ;; ERC function

(defn k? [item] (= k item))

(prn (k? k)) ;; true

(def erc-mult (er/rule (ex/ex (* ?x ?y)) :=> k
  :if (er/guard (and (k? ?x) (k? ?y)))
  ))

(def two (ex/ex (* k k)))

(prn (er/apply-rule erc-mult two))

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 manage k 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.

Activity

  1. Vaguery commented on May 8, 2019

    @Vaguery
    Author

    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.

  2. Vaguery commented on May 8, 2019

    @Vaguery
    Author

    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....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions