#631 assume hard to use programmatically

open
nobody
5
2006-04-10
2004-10-22
Stavros Macrakis
No

assume(r>0 and r<1)

works fine.

However, if I have a function

withassume(pred,expr) :=
( assume(pred), expand(expr) );

you get

withassume(r>0 and r<1, abs(r))
=> ERROR: can't eval predicate r>0

Quoting doesn't help:

withassume('(r>0 and r<1), abs(r)) => error
withassume('('(r>0) and '(r<1)), abs(r)) => error
withassume(('"and")(r>0) and '(r<1)), abs(r)) => error
withassume('("and")(r>0) and '(r<1)), abs(r)) => error

There is a workaround, however:

withassume(pred,expr) :=
( apply('assume,[pred]), expand(expr) );

You still have to quote the argument, but it works now:

withassume('(r>0 and r<1), abs(r)) => r

Alternatively, you can use the noun form of AND:

withassume('("and")(r>0,r<1),abs(r)) => r

Yuck in both cases.

------------------------------
Discussion

The underlying problem is that "is", "assume",
"forget", etc. quote their arguments then depend on
their own little idiosyncratic evaluator....

Also that noun-form logical connectives (and, or, if)
aren't really supported.

Maxima version: 5.9.0.9beta2
Maxima build date: 10:50 7/27/2004
host type: i686-pc-mingw32
lisp-implementation-type: Kyoto Common Lisp
lisp-implementation-version: GCL 2.6.3

Discussion

  • Robert Dodier
    Robert Dodier
    2006-04-10

    • labels: --> Lisp Core - Assume
     
  • Robert Dodier
    Robert Dodier
    2006-07-31

    Logged In: YES
    user_id=501686

    I know that this report is mostly about the general problem
    of using assume programmatically, but, writing withassume as
    a macro instead of a function yields the intended behavior I
    think:

    withassume(pred,expr) ::=buildq([pred, expr],
    block([result], assume(pred), result:expand(expr),
    forget(pred),result ));

    withassume(r>0 and r<1, abs(r));
    => r

    facts();
    => []

     
  • Logged In: YES
    user_id=588346

    Writing withassume as a macro instead of a function only
    works in the case of a constant argument. There is still no
    way to pass around the expression '(r>0 and r<1). For
    example, using the macro definition of withassume, the
    following still doesn't work:

    condition: '(r>0 and r<1)$
    withassume(condition, abs(r))

    Remember, macros are a syntactic fix. The underlying
    problems -- 1) that is/assume/etc. quote their arguments and
    2) that "and" cannot handle unevaluated conditions -- remain.

     
  • Robert Dodier
    Robert Dodier
    2006-12-26

    Logged In: YES
    user_id=501686
    Originator: NO

    The underlying problem is that "and", "or", and "not" cause Maxima to attempt evaluation of their operands. When r > 0 and r < 1 is benign, assume no longer needs to quote its argument. So implementation of unevaluated Boolean expressions is the key here. (I agree that buildq or other forms of quoting are a clumsy workaround.)

    In Maxima 5.10.99rc3:

    /* Define an assume function which evaluates its argument */
    (%i1) :lisp (defun $ev_assume (x) (funcall (get '$assume 'mfexpr*) `((foo) ,x)))
    $EV_ASSUME

    (%i1) withassume (pred, expr) := (ev_assume (pred), expand (expr));
    (%o1) withassume(pred, expr) := (ev_assume(pred), expand(expr))

    /* Here is the error that was originally reported */
    (%i2) withassume(r>0 and r<1, abs(r));
    Maxima was unable to evaluate the predicate:
    r > 0

    /* Load implementation of unevaluated Boolean expressions */
    (%i3) load (boolsimp);
    (%o3) /usr/share/maxima/5.10.99rc3/share/contrib/boolsimp/boolsi\ mp.lisp

    /* Try it again */
    (%i4) withassume(r>0 and r<1, abs(r));
    (%o4) r