Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support negative number representing symbols such as -E4 #42

Open
light-matters opened this issue Apr 26, 2024 · 6 comments
Open

Support negative number representing symbols such as -E4 #42

light-matters opened this issue Apr 26, 2024 · 6 comments
Labels
enhancement New feature or request

Comments

@light-matters
Copy link
Contributor

Would it be worth making it easier to pass negative symbols, e.g. '-E4 instead of '(- 0 E4).

At the moment, this will be interpreted as a non-alphanumeric symbol.

@light-matters light-matters added the enhancement New feature or request label Apr 26, 2024
@light-matters
Copy link
Contributor Author

light-matters commented May 14, 2024

Something like this seems to work (outputs {-y "Minus[y]", -x "Minus[x]"}) :

  (def expression '(+ -x -x -y -5 -2 (- x 10 5) (** x 2)))

  (defn strip-ns [form]
    (walk/postwalk (fn [form]
                     (if (qualified-symbol? form)
                       (symbol (name form))
                       form))
                   form))

   (defn replacement-map
    "Creates a replacement map for negative symbols, such that they are reasonably interpreted by Wolfram.

  TODO:
  - Extend the idea to deal with other custom replacements (e.g. greek/hebrew symbols.) .
  "
    [expression]
    (let [syms (->> expression
                    strip-ns
                    (into '())
                    (tree-seq list? seq)
                    (remove (some-fn list? nil?))
                    (filter #(when (symbol? %)
                               (->> %
                                    str
                                    (re-matches #"-.+"))))
                    distinct)

          syms-base (map (fn [sym] (-> sym str char-array rest (#(apply str %)) symbol)) syms)]

      (zipmap syms (map (fn [sym] (format "Minus[%s]" sym)) syms-base))))

  (replacement-map expression)
  (replacement-map `(+ -x -x -y -5 -2 (- x 10 5) (** x 2)))

Last two s-exps show that it works for quoted and backticked expressions.

@light-matters
Copy link
Contributor Author

light-matters commented May 14, 2024

Would it make more sense to actually do the replacement during the expression walk? This would require a fairly fundamental change to how wolframite usually works, but it would be powerful to have user-specified replacement functions.

At the moment, we can pass the generated replacement map to ->wl and it will get passed down the line, e.g.

(->wl '(+ -x -x -y -5 -2 (- x 10 5) (** x 2))
      {:aliases {'-x '(Minus x)
                   '-y '(Minus y)
                   '** 'Power}})

produces

#object[com.wolfram.jlink.Expr 0x23a65a14 "Plus[Minus[x], Minus[x], Minus[y], -5, -2, Subtract[x, 10, 5], Power[x, 2]]"]

@holyjak holyjak changed the title minus symbols Support negative number representing symbols such as -E4 Jun 28, 2024
@holyjak
Copy link
Member

holyjak commented Jun 28, 2024

Something like this seems to work ...

@light-matters Not sure these comments have anything to do with supporting negative symbols, as in -E4??

@holyjak
Copy link
Member

holyjak commented Jun 28, 2024

This could likely be implemented easily by extending wolframite.base.convert/convert impl. for :symbol, where we currently throw if the symbol does not match #"[^a-zA-Z0-9$\/]" - we could check that it is alphanum. and starts with - and replace that with Minus[...].

But this is not something Wolfram itself supports so IMO this is beyond v1. Notice that after #58 we will support (w/- E4).

Hm, what is E4 anyway? It does not seem Wolfram knows this? Is this meant for fn args, as in (w/Map (w/fn [x] -x) [1 2]) ??

@light-matters
Copy link
Contributor Author

Something like this seems to work ...

@light-matters Not sure these comments have anything to do with supporting negative symbols, as in -E4??

-E4 is symbolically equivalent to -x,-y etc. unless I misunderstand what you're meaning. I suppose it might have made more sense to use E4 as an example.

@light-matters
Copy link
Contributor Author

light-matters commented Jul 1, 2024

This could likely be implemented easily by extending wolframite.base.convert/convert impl. for :symbol, where we currently throw if the symbol does not match #"[^a-zA-Z0-9$\/]" - we could check that it is alphanum. and starts with - and replace that with Minus[...].

But this is not something Wolfram itself supports so IMO this is beyond v1. Notice that after #58 we will support (w/- E4).

Hm, what is E4 anyway? It does not seem Wolfram knows this? Is this meant for fn args, as in (w/Map (w/fn [x] -x) [1 2]) ??

Wolfram does support this, as I can evaluate "-x + 10" in Mathematica, but beyond v1 sounds right for us. As you say, (w/- E4) mostly solves the issue for now (it is better than having to write "(- 0 symbol)" just to make 'symbol' negative.

(wl/eval (w/- 'E4))
(wl/eval '(- E4))

both work as expected.

E4 is just an arbitrary symbol, e.g. 'equation4' or 'e' or 'x'. This was probaly a bad example, but just happened to be the thing I was working with when I reported the issue!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants