Page 1 of 1

Odd logical "AND" behaviour in TI

Posted: Fri Oct 24, 2014 1:24 am
by upali
Hi all,

TM1 version: 9.5.2

I saw this very odd behaviour in a logical operation in a TI Data tab and was wondering if you have seen a similar situation.

Code: Select all

if(Dimix(cDim, vGLCode) > 0 & CellIsUpdateable(cDestCube, vVersion, vYear, vPeriod, vCompanyCode, vProfitCentre, vGLCode) = 1);
	Prev_Value = CellGetN(cDestCube, vVersion, vYear, vPeriod, vCompanyCode, vProfitCentre, vGLCode);
	CellPutN (Prev_Value + Value, cDestCube, vVersion, vYear, vPeriod, vCompanyCode, vProfitCentre, vGLCode);
endif;
Naturally, like in all other programming languages I have used, I expected "IF" to evaluate the second expression if and only if the first expression to return true.
But,

Code: Select all

"Plan","2015","01","X","X_Z","1002","C9998DC","024700","7.083333333333333",Data Source line (1) Error: Data procedure line (15): Invalid key: Dimension Name: "GL_Code", Element Name (Key): "024700"
"Plan","2015","01","X","X_Z","1002","CCHEFDC","024700","7.083333333333333",Data Source line (2) Error: Data procedure line (15): Invalid key: Dimension Name: "GL_Code", Element Name (Key): "024700"
Line 15 is the "IF" statement.

So I tried this,

Code: Select all

if(CellIsUpdateable(cDestCube, vVersion, vYear, vPeriod, vCompanyCode, vProfitCentre, vGLCode) = 1);
	if(Dimix(cDim, vGLCode) > 0);
		Prev_Value = CellGetN(cDestCube, vVersion, vYear, vPeriod, vCompanyCode, vProfitCentre, vGLCode);
		CellPutN (Prev_Value + Value, cDestCube, vVersion, vYear, vPeriod, vCompanyCode, vProfitCentre, vGLCode);
	endif;
endif;
Gives the same error as above, which is fair enough.

But

Code: Select all

if(Dimix(cDim, vGLCode) > 0);
	if(CellIsUpdateable(cDestCube, vVersion, vYear, vPeriod, vCompanyCode, vProfitCentre, vGLCode) = 1);
		Prev_Value = CellGetN(cDestCube, vVersion, vYear, vPeriod, vCompanyCode, vProfitCentre, vGLCode);
		CellPutN (Prev_Value + Value, cDestCube, vVersion, vYear, vPeriod, vCompanyCode, vProfitCentre, vGLCode);
	endif;
endif;
Works fine without any error.

I'm puzzled. Does TI evaluate all the expressions? That doesn't make sense. I'd like to know if you've seen this before.

Thanks...

Re: Odd logical "AND" behaviour in TI

Posted: Fri Oct 24, 2014 3:18 am
by rmackenzie
This is expected behaviour because DIMIX doesn't need the element to exist in order to successfully evaluate - it will just return 0 for any string that is not an element/ alias of an element. CellGet/Put/Increment/N/S does require the element to exist otherwise you will you get the error.

In your first example - IF ( A & B ) then B has the issue so you get the error. Both clauses are evaluated because they are in the same statement.

In your second example - IF ( B ); IF ( A ) ... then the error is thrown on trying to evaluate B; A is not evaluated.

In your final example - IF ( A ); IF ( B ) ... then because A is False, it skips the rest of the IF statement - so no error.

IMO one may infer that Turbo Integrator is a one-pass compiler because of this behaviour. Also, note that when you are writing the TI, errors are reported one at a time, in the order that they are encountered and you need to fix each error in that same order.

Re: Odd logical "AND" behaviour in TI

Posted: Fri Oct 24, 2014 3:43 am
by upali
Thanks for the reply Robin
rmackenzie wrote: In your first example - IF ( A & B ) then B has the issue so you get the error. Both clauses are evaluated because they are in the same statement.
What I was expecting was; since A = FALSE there is no need to evaluate B (i.e. only one FALSE is enough to make an AND to be evaluated as FALSE). By trying to evaluate B the TI throws an error. If A = TRUE, then B should be evaluated, otherwise we don't know the final result if the IF().

Re: Odd logical "AND" behaviour in TI

Posted: Fri Oct 24, 2014 4:00 am
by rmackenzie
Your expectation is not outright unreasonable but consider an IF statement that has this structure: IF ( A % ( B & C ) )... even if B is FALSE the IF statement may still evaluate to TRUE if A is TRUE therefore it is necessary to evaluate C. That's why TI must evaluate both 'sides' of the AND even if this evaluation is sometimes redundant.

Also, note that in some versions, having an error thrown inside an IF statement sometimes meant the execution then stepped, in error, to the first line inside the IF block. Although verbose, I still tend to write things like:

Code: Select all

nCheck1 = CellGetN ( blah...);
nCheck2 = DIMIX ( blah... );
IF ( nCheck1 = 1 & nCheck2 = 1 );
  # etc
ENDIF;
However, it may very well have been fixed in later versions.

Re: Odd logical "AND" behaviour in TI

Posted: Fri Oct 24, 2014 4:05 am
by Alan Kirk
upali wrote:Thanks for the reply Robin
rmackenzie wrote: In your first example - IF ( A & B ) then B has the issue so you get the error. Both clauses are evaluated because they are in the same statement.
What I was expecting was; since A = FALSE there is no need to evaluate B (i.e. only one FALSE is enough to make an AND to be evaluated as FALSE). By trying to evaluate B the TI throws an error. If A = TRUE, then B should be evaluated, otherwise we don't know the final result if the IF().
Robin has pretty much answered your question but you should also be aware that not all languages work the way you're (not unreasonably) suggesting they should. T-SQL, for instance, may end up evaluating both but this will depend on exactly what the conditions are. I know that there are others but can't think of them off the top if my head. I always find it safer to nest blocks if one of my tests has the potential to evaluate to an error condition.

Re: Odd logical "AND" behaviour in TI

Posted: Sun Oct 26, 2014 10:00 pm
by Duncan P
TM1 does not have the optimization that only evaluates the right of a logical expression if needs to. It is stack based and it evaluates both sides, putting their results on the stack, before it sees that they are being combined with an "&".

Re: Odd logical "AND" behaviour in TI

Posted: Sun Oct 26, 2014 10:29 pm
by upali
Duncan P wrote:TM1 does not have the optimization that only evaluates the right of a logical expression if needs to. It is stack based and it evaluates both sides, putting their results on the stack, before it sees that they are being combined with an "&".
Ahh... if that's how this cookie crumbles, then let it be. I'll keep that in mind, not to assume such shortcuts. Thanks Duncan...