# PiecewiseExpand fails to address assumptions

PiecewiseExpand seems to ignore more complex assumptions. Here's an example:

exp = Piecewise[{{1, s[3, 2][t] - xp[2][t] < 0 && s[3, 2][t] - xp[3][t] < 0 && s[3, 5][t] - xp[3][t] > 0}, {2, s[3, 5][t] - xp[3][t] > 0}}, 3]

Define assumptions that eliminate the first two pieces:

$Assumptions = 0 < s[4, 5][t] < s[3, 5][t] < s[2, 5][t] < s[3, 4][t] < s[1, 5][t] < s[2, 4][t] < s[2, 3][t] < s[1, 4][t] < s[1, 3][t] < xp[5][t] < s[1, 2][t] < xp[4][t] < xp[3][t] < xp[2][t] < xp[1][t] < s[5, 4][t] < s[5, 3][t] < s[5, 2][t] < s[4, 3][t] < s[5, 1][t] < s[4, 2][t] < s[4, 1][t] < s[3, 2][t] < s[3, 1][t] < s[2, 1][t]  These assumptions imply s[3,2][t]>xp[3][t] and s[3,5][t]<xp[3][t] so only the last piece of exp applies. But PiecewiseExpand does not recognize this: PiecewiseExpand[exp]  yields no change in exp. The undocumented option "FullStrengthInference" doesn't help:  PiecewiseExpand[exp, Method -> {"FullStrengthInference" -> True}]  yields no change in exp. Even adding patterns reflecting the assumptions doesn't help: Assuming[(s[a_, b_][t] > xp[b_][t] && s[a_, b_][t] > xp[b_][t] && s[b_, a_][t] < xp[b_][t] && s[b_, a_][t] < xp[a_][t]) /; a > b, PiecewiseExpand[exp]]  yields no change in exp. Similarly Assuming[(s[a_, b_][t] > xp[b_][t] /; a > b) && (s[a_, b_][t] > xp[b_][t] /; a > b) && (s[b_, a_][t] < xp[b_][t] /; a > b) && (s[b_, a_][t] < xp[a_][t] /; a > b), PiecewiseExpand[exp, Method -> {"FullStrengthInference" -> True}]]  has no effect. Indeed, even winnowing down the assumptions doesn't fully resolve the issue: Assuming[s[3, 5][t] < xp[5][t] < xp[3][t] < s[3, 2][t], PiecewiseExpand[exp]]  yields two pieces: 2, which requires s[3,5][t] > xp[3][t], and 3. Most disappointing. Any ideas for overcoming this weakness are most welcome! Must I expand the assumptions into all implied pairwise comparisons? I hope not! And why don't the patterns in Assuming accomplish exactly that? Additional Comments: It seems PiecewiseExpand does not behave as advertised: $Version

(* 13.2.0 for Mac OS X x86 (64-bit) (November 18, 2022) *)

Clear["Global*"]

$Assumptions = 0 < s[4, 5][t] < s[3, 5][t] < s[2, 5][t] < s[3, 4][t] < s[1, 5][t] < s[2, 4][t] < s[2, 3][t] < s[1, 4][t] < s[1, 3][t] < xp[5][t] < s[1, 2][t] < xp[4][t] < xp[3][t] < xp[2][t] < xp[1][t] < s[5, 4][t] < s[5, 3][t] < s[5, 2][t] < s[4, 3][t] < s[5, 1][t] < s[4, 2][t] < s[4, 1][t] < s[3, 2][t] < s[3, 1][t] < s[2, 1][t]; exp = Piecewise[{{1, s[3, 2][t] - xp[2][t] < 0 && s[3, 2][t] - xp[3][t] < 0 && s[3, 5][t] - xp[3][t] > 0}, {2, s[3, 5][t] - xp[3][t] > 0}}, 3] (* Piecewise[{{1,s[3,2][t]-xp[2][t]<0&&s[3,2][t]-xp[3][t]<0&&s[3,5][t] -xp[3][t]>0},{2,s[3,5][t]-xp[3][t]>0}},3] *) PiecewiseExpand[exp, Method -> {"ConditionSimplifier" -> Reduce}] (* Piecewise[{{2,xp[3][t]<s[3,5][t]}},3]*)  One expects ConditionSimplifier -> Reduce to work as follows: myPiecewiseExpand[args__] := With[{expression = PiecewiseExpand[args]}, (* Delete conditions that evaluate to False *) With[{pieces = DeleteCases[First[expression], {val_, cond_}/;\[Not]Reduce[cond &&$Assumptions]]},
If[Length[pieces] > 0,
Piecewise[pieces,Last[expression]],
Last[expression]]]];


That gives the expected results:

myPiecewiseExpand[exp]

(* 3 *)

$Assumptions = True; myPiecewiseExpand[exp] (* Piecewise[{{1, s[3, 2][t] - xp[2][t] < 0 && s[3, 2][t] - xp[3][t] < 0 && s[3, 5][t] - xp[3][t] > 0}, {2, s[3, 5][t] - xp[3][t] > 0}}, 3] *)  ## 1 Answer $Version

(* "13.3.1 for Mac OS X ARM (64-bit) (July 24, 2023)" *)

Clear["Global*"]

$Assumptions = 0 < s[4, 5][t] < s[3, 5][t] < s[2, 5][t] < s[3, 4][t] < s[1, 5][t] < s[2, 4][t] < s[2, 3][t] < s[1, 4][t] < s[1, 3][t] < xp[5][t] < s[1, 2][t] < xp[4][t] < xp[3][t] < xp[2][t] < xp[1][t] < s[5, 4][t] < s[5, 3][t] < s[5, 2][t] < s[4, 3][t] < s[5, 1][t] < s[4, 2][t] < s[4, 1][t] < s[3, 2][t] < s[3, 1][t] < s[2, 1][t]; exp = Piecewise[{{1, s[3, 2][t] - xp[2][t] < 0 && s[3, 2][t] - xp[3][t] < 0 && s[3, 5][t] - xp[3][t] > 0}, {2, s[3, 5][t] - xp[3][t] > 0}}, 3] (* Piecewise[{{1, s[3, 2][t] - xp[2][t] < 0 && s[3, 2][t] - xp[3][t] < 0 && s[3, 5][t] - xp[3][t] > 0}, {2, s[3, 5][t] - xp[3][t] > 0}}, 3] *)  $Assumptions only affects functions that use the option Assumptions

{#, Options[#]} & /@ {Piecewise, PiecewiseExpand, Simplify} //
Grid[#, Frame -> All] &


exp // PiecewiseExpand

(* Piecewise[{{2, s[3, 5][t] - xp[3][t] > 0}}, 3] *)

exp // Simplify

(* Piecewise[{{2, s[3, 5][t] > xp[3][t]}}, 3] *)


Piecewise will always have at least two parts since the default is always included to cover conditions not meeting any of the given conditions.

EDIT: Piecewise has the attribute HoldAll

Attributes[Piecewise]



PiecewiseExpand does not cause the Piecewise to evaluate, it tries to simplify (using \$Assumptions) the form of the Piecewise. Separate effort is required to evaluate the Piecewise.

exp // PiecewiseExpand


Assuming[s[3, 5][t] < xp[3][t], exp // PiecewiseExpand]

(* 3 *)


or

Assuming[s[3, 5][t] < xp[3][t], exp // Simplify]

(* 3 *)

• Bob, thanks so much for considering my question. Apologies, I am confused by your answer. The documentation indicates (DollarSign)Assumptions is the default value of Assumptions in PiecewiseExpand. And indeed, setting: (DollarSign)Assumptions = s[3, 5][t] < xp[5][t] < xp[3][t] < s[3, 2][t] && s[3, 5][t] < xp[3][t]; PiecewiseExpand[exp] (* 3 *) yields the correct and desired result: 3. Nov 27, 2023 at 14:22
• See if the edit answers your question. Nov 27, 2023 at 20:15