@peter.ludemann
Next interesting observation (probably a feature, not a bug). The C++ PREDICATE(name, arity) macros only catch Prolog exceptions. I have to catch the c++ exceptions myself:
Here, I catch the exception from libarmadillo in the code:
?- matrix(2, 2, A), eye(A), matrix(3, 3, B), ones(B), mult(A, B, M).
ERROR: Domain error: `matrix multiplication: incompatible matrix dimensions: 2x2 and 3x3' expected, found `Matrix(rows=2 cols=2)*Matrix(rows=3 cols=3)'
ERROR: In:
ERROR: [11] mult(Matrix(rows=2 cols=2),Matrix(rows=3 cols=3),_1990)
ERROR: [10] '<meta-call>'('<garbage_collected>') <foreign>
ERROR: [9] toplevel_call('<garbage_collected>') at /usr/lib/swi-prolog/boot/toplevel.pl:1173
?- halt.
Note that control is back at top level.
Here, I don’t catch the exception:
?- matrix(2, 2, A), eye(A), column(3, B), ones(B), mult(A, B, M).
terminate called after throwing an instance of 'std::logic_error'
what(): matrix multiplication: incompatible matrix dimensions: 2x2 and 3x1
Aborted
$
Note that swipl terminated, and I am back at the command prompt.
That is the C++ code:
PREDICATE(mult, 3)
{ PL_blob_t *t1, *t2 ;
if(A1.is_blob(&t1) && t1 == &matrix && A2.is_blob(&t2) && t2 == &matrix)
{ auto m1 = PlBlobV<Matrix>::cast_ex(A1, matrix) ;
auto m2 = PlBlobV<Matrix>::cast_ex(A2, matrix) ;
try
{ mat m = m1->m * m2->m ;
auto ref = std::unique_ptr<PlBlob>(new Matrix(m)) ;
return A3.unify_blob(&ref) ;
}
catch(std::exception& e)
{ throw PlDomainError(e.what(), PlCompound("*", PlTermv(A1, A2))) ;
}
}
if(A1.is_blob(&t1) && t1 == &matrix && A2.is_blob(&t2) && t2 == &column)
{ auto m1 = PlBlobV<Matrix>::cast_ex(A1, matrix) ;
auto m2 = PlBlobV<Column>::cast_ex(A2, column) ;
mat m = m1->m * m2->v ;
auto ref = std::unique_ptr<PlBlob>(new Matrix(m)) ;
return A3.unify_blob(&ref) ;
}
etc.