Open byjtew opened 1 year ago
Negation is a powerful tool, and would enable a whole bunch of new recipes for auto-parallelisation. However, for that to work, negation I believe should be an (algebraic) type trait, e.g.,
grb::has_negation< OP >::value;
grb::has_negation< OP >::Operator;
Similar type traits could be
grb::has_monoid< OP >::value;
grb::has_monoid< OP >::Monoid;
with the latter promoting a given operator to a natural monoid, if one associated one exists.
What this could do, for example, is parallelise grb::foldl( scalar, array, grb::operators::subtract() )
, by translating it into
auto negated_reduction = grb::has_negation< OP >::Operator >::getIdentity();
grb::foldl( negated_reduction, array, grb::has_monoid< grb::has_negation< OP >::Operator >::Monoid() ); // this is parallel
grb::foldl( scalar, negated_reduction, grb::operators::subtract() ); // this need not be parallel
Or did you mean negate as in purely the Boolean form of it? (In that case, I would call it logical_not
, in line with the other Boolean operators, and your proposal looks good)
Or did you mean negate as in purely the Boolean form of it? (In that case, I would call it
logical_not
, in line with the other Boolean operators, and your proposal looks good)
I meant boolean negation, which should be logical_not indeed.
I don't understand your first idea tbh.
We can go over it on a blackboard sometime, it's also very fun to try out. (But better to do in a separate MR for sure)
Operator wrapper allowing to negate its result.
The point of this feature it to not need to fully implement new operators using operators::negate. For instance operators::logical_nand becomes: