1
$\begingroup$

I'd like to add asserts which check for condition, print useful message and abort computation on failure.

IE,

Assert[MatrixQ[mat], "mat not a matrix: "~StringJoin~ToString[mat]]

Currently using this in a function, the message is printed, but the computation continues.

I've tried various recipes in stop notebook evaluation when Assert fails , and none of them worked for me in Mathematica 12.0 (either they don't abort computation, or don't print the message, or they kill the whole kernel instead of just aborting current computation), any suggestions?

Test case:

zeroOutColumn[mat_, col_] := Module[{mask},
   Assert[MatrixQ[mat], "mat not a matrix: "~StringJoin~ToString[mat]];
   Assert[1 <= col <= Last[Dimensions[mat]], "col not a valid column"];
   mask = Array[Boole[#2 != col] &, Dimensions[mat]];
   mat*mask
   ];
zeroOutColumn[automaticHess, 80]
$\endgroup$
  • $\begingroup$ Is this any help?: assertFunction[HoldComplete@Assert[code_, tag_]] := (Print[tag]; Abort[]); $AssertFunction = assertFunction[##] & $\endgroup$ – Michael E2 Sep 22 '19 at 14:47
0
$\begingroup$

Here is a very hacky way to achieve your goals. Conditionally redefine MakeExpression so that it fails when an assertion occurs. The evaluator will immediately stop evaluating the current cell, although it will continue to try to evaluate other cells that may be in the evaluation queue:

On[Assert]
$AssertFunction := (
    StylePrint[#[[1,2]],"Assert"];
    SelectionMove[EvaluationNotebook[], All, Notebook,AutoScroll->False];
    FrontEndTokenExecute @ "RemoveFromEvaluationQueue";
    SelectionMove[NextCell[CellStyle -> "Assert"], After, Cell, AutoScroll->False];
    $Assertion=True;
)&

MakeExpression[x_, form_] /; TrueQ@$Assertion := ($Assertion=False;Null)

Example.

Before evaluation (notice 3 cells are selected):

enter image description here

After evaluation:

ix

Notice that only Out[175] evaluated, as it was before the assert, and the assert function killed everything after the Assert.

| improve this answer | |
$\endgroup$
  • $\begingroup$ Hm, this does something strange -- if I run my test case twice (added into question body), the second time I run it, nothing is produced. I'm also wondering if I'm misusing Assert here -- there are internal functions that abort computation + print warning when things are bad, is that done in a different way? $\endgroup$ – Yaroslav Bulatov Aug 23 '19 at 13:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.