Issue 3025 in sympy: Piecewise evaluate=False does not work when conditions are boolean

4 views
Skip to first unread message

sy...@googlecode.com

unread,
Jan 24, 2012, 9:17:26 PM1/24/12
to sympy-...@googlegroups.com
Status: New
Owner: ----
Labels: Type-Defect Priority-Medium

New issue 3025 by sean.v....@gmail.com: Piecewise evaluate=False does not
work when conditions are boolean
http://code.google.com/p/sympy/issues/detail?id=3025

Because bool's are not allowed in args, and without a Boolean subclassing
basic, bools as conditions force evaluation regardless of evaluate option.

Opening this issue is based on changes in pull #1009 [1] so it can be
referenced in the pull.

[1] https://github.com/sympy/sympy/pull/1009

sy...@googlecode.com

unread,
Feb 25, 2012, 6:43:48 PM2/25/12
to sympy-...@googlegroups.com
Updates:
Status: Accepted

Comment #1 on issue 3025 by asme...@gmail.com: Piecewise evaluate=False

does not work when conditions are boolean
http://code.google.com/p/sympy/issues/detail?id=3025

That will probably be merged separately from Basic booleans, which means
that this will probably raise NotImplementedError.

sy...@googlecode.com

unread,
Feb 26, 2012, 2:30:42 PM2/26/12
to sympy-...@googlegroups.com

Comment #2 on issue 3025 by Ronan.L...@gmail.com: Piecewise evaluate=False
does not work when conditions are boolean
http://code.google.com/p/sympy/issues/detail?id=3025

Generally speaking, I think we should avoid evaluate=False (cf. issue 273),
and in any case I don't see any use for having explicitly False conditions
in Piecewise, or for multiple True conditions either.

sy...@googlecode.com

unread,
Feb 26, 2012, 2:35:43 PM2/26/12
to sympy-...@googlegroups.com

Comment #3 on issue 3025 by Ronan.L...@gmail.com: Piecewise evaluate=False
does not work when conditions are boolean
http://code.google.com/p/sympy/issues/detail?id=3025

Generally speaking, I think we should avoid evaluate=False (cf. issue 274),

sy...@googlecode.com

unread,
Feb 26, 2012, 3:17:53 PM2/26/12
to sympy-...@googlegroups.com

Comment #4 on issue 3025 by asme...@gmail.com: Piecewise evaluate=False
does not work when conditions are boolean
http://code.google.com/p/sympy/issues/detail?id=3025

As Sean was explaining in the pull request, multiple True conditions makes
sense if you want to be vague in the definition of the Piecewise, like
Piecewise((2*x, x >=0), (-2*x, x <=0)). Notice that at 0, both conditions
are True, but also both expressions are equal at that point. In general,
we would have to do equivalence checking to see if this is the case, but I
don't see any reason to do so. Just go with the first True condition.

One could also use this fact to be lazy about the definition of the
conditions. For example, instead of writing Piecewise((x, x > 0), (y,
And(x < 0, x > -1))), one could just write Piecewise((x, x > 0), (y, x >
-1)). While I wouldn't necessarily recommend doing this, especially if you
are going to use the printed output at all, it can be a convenience
interactively, for example.

I can think of a couple of cases where evaluate=False might be useful, such
as intermediate steps to some algorithm that wants things to always line
up, or as a way to keep the information in the Piecewise around (delayed
evaluation). And anyway, I don't see any harm in allowing it.

sy...@googlecode.com

unread,
Feb 26, 2012, 9:06:38 PM2/26/12
to sympy-...@googlegroups.com

Comment #5 on issue 3025 by sean.v....@gmail.com: Piecewise evaluate=False
does not work when conditions are boolean
http://code.google.com/p/sympy/issues/detail?id=3025

The primary benefit to evaluate=False is, like Aaron mentioned, delayed
evaluation when some conditions may be bools. This is the case in
meijerint, where at one point, the algorithm creates a Piecewise function,
where even though some conditions are True, it shouldn't be evaluated. The
commit 5657506e in the PR, where I have evaluate=False with bools raise an
error, highlights this, where the conditions have to be checked and any
bools properly dealt with, where this could be avoided with evaluate=False.

I skimmed some of the related issues to the evaluate=False stuff, and while
I see where not evaluating can be a pain, the evaluation of a Piecewise
function isn't the same as turning log(1) into 0 or Mul(3,4) into 12.
Whatever it's called, there should be some way to delay evaluation, so for
example, you could hold onto Piecewise((x,x<0),(y,True)) until you have a
value for x before you evaluate.

sy...@googlecode.com

unread,
Feb 26, 2012, 10:51:03 PM2/26/12
to sympy-...@googlegroups.com

Comment #6 on issue 3025 by Ronan.L...@gmail.com: Piecewise evaluate=False
does not work when conditions are boolean
http://code.google.com/p/sympy/issues/detail?id=3025

Sean & Aaron: None of the examples you mention have explicitly True or
False conditions, so they don't address my point, which is that there are
no circumstances where 'Piecewise((x, True), (y, False), (z, True))' is
preferable to 'x'.

Also, I don't understand the initial comment, given that 'evaluate=False'
is actually obeyed, causing rather nonsensical results:

In [17]: Piecewise((x, x>1), (0, True), (1, False), (2, True),
evaluate=False)
Out[17]:
⎧x for x > 1

⎪0 otherwise

⎪1 for False

⎩2 otherwise


sy...@googlecode.com

unread,
Feb 27, 2012, 12:01:19 AM2/27/12
to sympy-...@googlegroups.com

Comment #7 on issue 3025 by asme...@gmail.com: Piecewise evaluate=False
does not work when conditions are boolean
http://code.google.com/p/sympy/issues/detail?id=3025

Is that in Sean's branch? We should do all discussion there, as Piecewise
is broken in master, and it will be confusing about what syntax we are
talking about.

sy...@googlecode.com

unread,
Feb 28, 2012, 1:08:19 PM2/28/12
to sympy-...@googlegroups.com

Comment #8 on issue 3025 by Ronan.L...@gmail.com: Piecewise evaluate=False
does not work when conditions are boolean
http://code.google.com/p/sympy/issues/detail?id=3025

Let's use this to discuss what evaluate=False *should* do.

#6 describes current behaviour in master. I think that it's wrong, and that
Piecewise((x, x>1), (0, True), (1, False), (2, True)) should always be
canonicalised to Piecewise((x, x>1), (0, True)), irrespective of issue 2626.

sy...@googlecode.com

unread,
Feb 28, 2012, 2:40:58 PM2/28/12
to sympy-...@googlegroups.com
Updates:
Labels: -Priority-Medium Priority-High

Comment #9 on issue 3025 by asme...@gmail.com: Piecewise evaluate=False

does not work when conditions are boolean
http://code.google.com/p/sympy/issues/detail?id=3025

To summarize a discussion from the pull request:

Piecewise((x, x > 1), (0, True), nan) in Sean's branch evaluates to 0,
because (0, True) is parsed as an expr, cond pair, and since the condition
is True, it returns the expression. evaluate=False would allow to keep
this from evaluating, which would be desirable if x is later evaluated to
something greater than 1, in which case you would get x (whatever it is),
not 0 (or at least that was my opinion; Ronan hasn't stated his yet).

In other words, you can consider Piecewise((x, x > 1), (0, True), nan) as

if x > 1: return x
elif True: return 0
else: return nan

If x is given, this should return x, not 0.

On the other hand, if Piecewise does not evaluate to explicitly True
conditions, it will be useless.

Let me know if I've left anything out. I don't know if you wanted to
discuss the IfElse here as well.

> #6 describes current behaviour in master. I think that it's wrong, and
> that Piecewise((x, x>1), (0, True), (1, False), (2, True)) should always
> be canonicalised to Piecewise((x, x>1), (0, True)), irrespective of issue
> 2626.

I definitely agree that it's wrong, and was probably never intentioned to
do that, but rather is just a side effect of the way the current
parser/printer works.

It doesn't make sense to say "Piecewise((x, x>1), (0, True)), irrespective
of issue 2626." because those mean different things in master and in Sean's
branch (or technically, master and Sean's branch after we end the
deprecation cycle). That's why I think we should just discuss things in
terms of the new syntax, so that we are clear about what we mean (hence, we
could talk about Piecewise((x, x>1), (0, True), nan), which is unambiguous
in the new syntax due to redundancy, even with deprecation).

This is what I meant when I said "let's do all discussions there," by the
way, that we should discuss things using the new syntax, not necessarily
that the discussion itself should be in the pull request. Sorry if there
was ambiguity there.

sy...@googlecode.com

unread,
Feb 28, 2012, 11:43:45 PM2/28/12
to sympy-...@googlegroups.com

Comment #10 on issue 3025 by Ronan.L...@gmail.com: Piecewise evaluate=False
does not work when conditions are boolean
http://code.google.com/p/sympy/issues/detail?id=3025

I'd rather base the discussion on the existing behaviour (and ignore the
difference between evaluating to nan and raising ValueError), because there
are things in Sean's branch I don't understand at all, such
as "Piecewise((x, x > 1), (0, True), nan) in Sean's branch evaluates to 0,

because (0, True) is parsed as an expr, cond pair, and since the condition

is True, it returns the expression." I don't see why the 2nd condition
being True should cause the Piecewise to evaluate to 0.

sy...@googlecode.com

unread,
Feb 29, 2012, 12:02:56 AM2/29/12
to sympy-...@googlegroups.com

Comment #11 on issue 3025 by sean.v....@gmail.com: Piecewise evaluate=False
does not work when conditions are boolean
http://code.google.com/p/sympy/issues/detail?id=3025

Ronan, what I understand as the rationalization of that behavior is if a
boolean condition is encountered, it is because there was an evaluation
step, such as .subs(), causing one of the conditions to be either True or
False, and so the Piecewise expression is expected to be evaluated, where
evaluation is returning one of the expressions. Namely, the first
expression with a condition of True, even if that means skipping
expressions with unevaluated conditions. Because of this, if you want to
use a Piecewise in an algorithm, if some conditions may be booleans, but
you want to delay evaluation, you would need something like evaluate=False
to do this (meijerint is an example of this).

sy...@googlecode.com

unread,
Feb 29, 2012, 2:47:11 PM2/29/12
to sympy-...@googlegroups.com

Comment #12 on issue 3025 by Ronan.L...@gmail.com: Piecewise evaluate=False
does not work when conditions are boolean
http://code.google.com/p/sympy/issues/detail?id=3025

Well, that's just wrong! Whenever this triggers, it returns results that
are incompatible with the definition of Piecewise.

sy...@googlecode.com

unread,
Feb 29, 2012, 3:28:06 PM2/29/12
to sympy-...@googlegroups.com

Comment #13 on issue 3025 by asme...@gmail.com: Piecewise evaluate=False
does not work when conditions are boolean
http://code.google.com/p/sympy/issues/detail?id=3025

As I stated before, if this doesn't happen, Piecewise will become
completely useless.

sy...@googlecode.com

unread,
Feb 29, 2012, 3:42:15 PM2/29/12
to sympy-...@googlegroups.com

Comment #14 on issue 3025 by Ronan.L...@gmail.com: Piecewise evaluate=False
does not work when conditions are boolean
http://code.google.com/p/sympy/issues/detail?id=3025

But why?? It already exists and is useful - without this puzzling feature.

sy...@googlecode.com

unread,
Feb 29, 2012, 3:54:24 PM2/29/12
to sympy-...@googlegroups.com

Comment #15 on issue 3025 by asme...@gmail.com: Piecewise evaluate=False
does not work when conditions are boolean
http://code.google.com/p/sympy/issues/detail?id=3025

I disagree with that. For example, the bizarre output in comment 8 (two
otherwise conditions) is a direct result of the way it's done now (granted,
it's likely due to an oversight as I noted, but if it were done the way as
it's done in Sean's branch, that would never have happened).

To me, (otherwise, True) is confusing. In a piecewise, (expr, cond) should
mean return expr when cond is True. But the way it's done now turns
directly contradicts that.

With the new way, we can assert this: that if a condition is True, that's
what is returned. I don't see what's puzzling about that.

By the way, if we're going to argue about the new syntax, perhaps it should
be over at issue 2626, where I've already made many arguments about it (and
several people agreed).

sy...@googlecode.com

unread,
Feb 29, 2012, 4:35:53 PM2/29/12
to sympy-...@googlegroups.com

Comment #16 on issue 3025 by Ronan.L...@gmail.com: Piecewise evaluate=False
does not work when conditions are boolean
http://code.google.com/p/sympy/issues/detail?id=3025

The new syntax only affects the end of the argument list. Here, we're
discussing the meaning of the arguments in the middle.

A lone pair doesn't really mean anything, since all the conditions before
it have to be evaluated - just like an elif statement can't really be
understood if you don't know what went before. What you're suggesting
amounts to making Piecewise non-deterministic, e.g. with p = Piecewise((1,
x > 0), (2, y > 0), 3) [your new syntax and semantics], p.subs(x,
1).subs(y, 1) == 1 but p.subs(y, 1).subs(x, 1) == 2.


sy...@googlecode.com

unread,
Feb 29, 2012, 4:49:04 PM2/29/12
to sympy-...@googlegroups.com

Comment #17 on issue 3025 by Ronan.L...@gmail.com: Piecewise evaluate=False
does not work when conditions are boolean
http://code.google.com/p/sympy/issues/detail?id=3025

I just sent a PR fixing the issue in #c8 without changing the semantics of
Piecewise:

https://github.com/sympy/sympy/pull/1095

sy...@googlecode.com

unread,
Feb 29, 2012, 5:50:51 PM2/29/12
to sympy-...@googlegroups.com

Comment #18 on issue 3025 by asme...@gmail.com: Piecewise evaluate=False
does not work when conditions are boolean
http://code.google.com/p/sympy/issues/detail?id=3025

Well, you could argue that such non-determinism is due to an ill-defined
piecewise expression. What *should* the piecewise function be if both x
and y are positive?

I guess the confusion here comes from looking at a piecewise both in it's
mathematical sense, where the order of the conditions is generally not
considered to matter, and things like Piecewise((1, x > 0), (2, y > 0), 3)
are considered ill-defined, and in the programing language sense of nested
or chained if-else clauses, where the order does matter.

So maybe we should have a way to represent both? I can see how the latter
could be useful, but the inability to evaluate symbolic inequalities in
general would make it useless for a mathematical definition of a piecewise
(because to be consistant, it should *never* evaluate unless the first
non-False condition is explicitly True).

sy...@googlecode.com

unread,
Feb 29, 2012, 11:16:13 PM2/29/12
to sympy-...@googlegroups.com

Comment #19 on issue 3025 by Ronan.L...@gmail.com: Piecewise evaluate=False
does not work when conditions are boolean
http://code.google.com/p/sympy/issues/detail?id=3025

I don't know what you mean by "a piecewise". I don't think that it's a
well-defined mathematical object and, since "piecewise" is an adverb, "a
piecewise" doesn't even seem grammatically correct.

OTOH, until now, the behaviour of Piecewise has been clearly defined as
evaluating the conditions in sequence.

But I guess that the problem is that Piecewise is actually a complicated
way of modelling conditional expressions, while it claims to represent
piecewise-defined functions. So I think that we need a simple
implementation of conditional expressions (IfElse), and a representation of
piecewise-defined functions over the reals. The latter would have an
implementation very different from Piecewise, because it would be a
function instead of an expression and because it would probably rely on
explicit intervals forming a disjoint cover of the real line, which would
allow efficient evaluation by bisecting on the breakpoints.

sy...@googlecode.com

unread,
Mar 2, 2012, 9:34:08 AM3/2/12
to sympy-...@googlegroups.com

Comment #20 on issue 3025 by julien.r...@gmail.com: Piecewise
evaluate=False does not work when conditions are boolean
http://code.google.com/p/sympy/issues/detail?id=3025

+1 for keeping the current sequential evaluation of conditions in Piecewise.

By the way, I use Piecewise right now, it is useful and I don't find the
syntax broken. It should just canonize as described in comment #8.

sy...@googlecode.com

unread,
Jul 9, 2012, 10:38:41 AM7/9/12
to sympy-...@googlegroups.com
Updates:
Blockedon: -2531 sympy:2531

Comment #22 on issue 3025 by julien.r...@gmail.com: Piecewise
evaluate=False does not work when conditions are boolean
http://code.google.com/p/sympy/issues/detail?id=3025

The pull request has been merged, this seems fixed.

sy...@googlecode.com

unread,
Jul 16, 2012, 3:49:19 AM7/16/12
to sympy-...@googlegroups.com
Updates:
Status: Started
Owner: julien.r...@gmail.com
Labels: NeedsReview

Comment #23 on issue 3025 by julien.r...@gmail.com: Piecewise
evaluate=False does not work when conditions are boolean
http://code.google.com/p/sympy/issues/detail?id=3025

Actually, one last fix for this is at
https://github.com/sympy/sympy/pull/1421 in commit bfd04ae.

Reply all
Reply to author
Forward
0 new messages