From: Dumaiu <dy...@gm...> - 2015-03-16 01:05:19
|
The class of problem I am dealing with here concerns getting the Maxima simplifier to do as much of my work as possible in reducing operator expressions. Considering, for the example of the moment, propositional logic, it would be desirable for some long thing like 'a ∧ (b ∧ (c ∧ (0 ∧ d))) ∧ (e ∧ f)' to reduce automatically to 0. My first strategy was to employ both varieties of 'nary': nary("∧"); declare("∧",[commutative,nary]); because it would yield simpler canonical forms; however, I can't find a way to use tellsimp() meaningfully therewith. To prevent arbitrarily hairy matching, tellsimp() requires a main operator, so there would need to be a pattern for matching against variadic argument lists. I recognize that such a technique, if it does exist, will handle most of my difficulties, but I haven't found it; tellsimp("∧"([args]),…) doesn't do what I think I wish it did. My second idea was to use a lassociative declaration: nary("∧"); /* infix() would be logical, but it runs afoul of bug #2920 <http://sourceforge.net/p/maxima/bugs/2920/>, a few words about which later */ declare("∧", [commutative, lassociative]); matchdeclare(var,true); tellsimp(0 ∧ var,0); But then--! (%i10) a ∧ (b ∧ (c ∧ (0 ∧ d))) ∧ (e ∧ f); ⟹ Maxima encountered a Lisp error: Error in MACSYMA-TOP-LEVEL [or a callee]: 0 is not of type LIST. Some part of the simplifier dislikes the fact that (∧rule1) returns an atom. OK; as a workaround, we switch categories. Re-formulating the example with set-theoretic operations and '{}' the zero element: nary("∩"); declare("∩", [commutative, lassociative]); tellsimp({} ∩ var, {}); This gets me almost what I want: (%i12) a ∩ (b ∩ (c ∩ ({} ∩ d))) ∩ (e ∩ f); (%o12) {} ∩ a ∩ e ∩ f (%i13) ev(%); (%o13) {} And that is where I stand currently. My hypothesis about using lassociative to "curry" expressions into binary form for submission to commutative rules receives some support, and perhaps setting infeval is the next thing for me to try; but I would like to avail myself of the experts' knowledge before going further. If I had to venture a guess, I would say that #2920, the "wrong number of arguments" bug, is a result of (lassociative) and (rassociative) being written with functions, and not operators, in mind. These guys flatten nested arguments and pass them to (oper-apply) as a three-element list, which, after some recursion, reinstalls the parentheses as desired; if the operator can't take three arguments, i.e., because binary infix, you get the arity complaint. Though I freely admit the possibility of more than one kind of operator error's being in play here, if you'll pardon the pun, I do suspect that the other major issue I encountered--when a tellsimp() rule produced a type error--is also indicative of a bug in (l|r)associative. It's apparent from the definition (Maxima 5.35.1) that (lassociative) expects to receive a Maxima cons for its first parameter: (defmfun lassociative (e z) (let* ((ans0 (oper-apply (cons (car e) (total-nary e)) z)) (ans (cdr ans0))) (cond ((or (null (cddr ans)) (not (eq (caar ans0) (caar e)))) ans0) ((do ((newans (list (car e) (car ans) (cadr ans)) (list (car e) newans (car ans))) (ans (cddr ans) (cdr ans))) ((null ans) newans)))))) This suggests that there may be some quoting/unquoting workaround for my 'tellsimp(0 ∧ var,0)' example. Thanks for your time reading this, Jonathan Jakes-Schauer |