Re: How to tell Mathematica to stop conditional testing in an If statment if one condition is niether True or False? McCarthy evaluation rules? 'and then' test?
- To: mathgroup at smc.vnet.net
- Subject: [mg69563] Re: [mg69525] How to tell Mathematica to stop conditional testing in an If statment if one condition is niether True or False? McCarthy evaluation rules? 'and then' test?
- From: Daniel Lichtblau <danl at wolfram.com>
- Date: Fri, 15 Sep 2006 06:46:37 -0400 (EDT)
- References: <200609141057.GAA21660@smc.vnet.net>
Nasser Abbasi wrote: > I can better describe this with simple example: > > ------------- code ------------ > > Remove["Global`*"]; > xc = Table[i, {i, 1, 3}] > x = 5; > If[x == b && xc[[10]] == 4, Print["True"], Print["False"], Print["Can't > decide"]] > > ----- end code ------------- > In the above, 'x==b' is neither True nor False, since 'b' has no numerical > value. > > But what I want is when this happens, for Mathematica to NOT continue with > the testing if xc[[10]]==4 is True (because even if it is True, it will > not change the outcome, which is can't decide. > > I am looking for something like 'and then' which says to test the next > condition only if the one just tested was true. Can be done. See below for a couple of possibilities. > The interesting thing is that if 'b' had a value, say 7, which makes the > first test (the x==b) to be False, then Mathematica does the right thing, > and will not try to check the xc[[10]]==4 condition. I need it to do the > same thing when also the result of the check is 'undecided', not just > 'False' or 'True'. > > Is there a way to do this? Notice in the example above, I get the error > that xc[[10]] is out of bound, but still get the can't decide message. > > It is clear to me that the way Mathematica does it now is not the right way. This is a questionable viewpoint. > I do not see why it tries to check for xc[[10]]==4 when it will not make a > difference to the final result. > > any thoughts? > > thanks, > Nasser The functions And and Or are already overburdened by being both logical and programming functions. As the former, it is appropriate to reorder (And is commutative) and to apply De Morgan's laws, etc. For the latter purpose, as your example makes clear, reordering is not appropriate due to possibility of bad side effects. But Mathematica evaluation will only short-circuit if And encounters a False, or Or encounters a True. I think this is as it should be because a partial evaluation, when short circuiting does not occur, is a sensible thing (there might be side effects that programmers rely upon taking place). To get to your example, here are a couple of possibilities. (1) Tailored to the specific problem at hand. If [TrueQ[x == b], If [xc[[10]] == 4, Print["True"], Print["False"], Print["Can't decide"]], If [TrueQ[x!=b], Print["False"], Print["Can't decide"]] ] (2) More generally, you might want to pass a list of conditions. If all are TrueQ, return True. Else if the first that is not is False return False, else cannot decide. myIf[conds_List, then_, else_, otherwise_] := Module[ {j=1,len, ucond=Apply[Hold,Unevaluated[conds]]}, len = Length[ucond]; While [j<=len && TrueQ[Extract[ucond,{j}]], j++]; If [j>len, then, If [TrueQ[!Extract[ucond,{j}]], else, otherwise]] ] For your example, with xc and x initialized as you do: In[73]:= myIf[{x==b,xc[[10]]==4}, Print["True"], Print["False"], Print["Can't decide"]] Can't decide In[74]:= Daniel Lichtblau Wolfram Research
- References: