Skip to content

Commit

Permalink
Add terminal pruning for initial transposition sweep (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
SSoelvsten committed Apr 18, 2024
1 parent 6c40419 commit 17c49e3
Show file tree
Hide file tree
Showing 3 changed files with 867 additions and 80 deletions.
172 changes: 170 additions & 2 deletions src/adiar/internal/algorithms/quantify.h
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,36 @@ namespace adiar::internal
continue;
}

// -----------------------------------------------------------------------------------------
// CASE: Pruning Quantification
// Prune based on terminals for shallow to-be quantified variables dealt with during
// nested sweeping.
if constexpr (Policy::pruning_quantification) {
if (policy.should_prune()) {
adiar_assert(req.target.second().is_nil(),
"Pruning should only happen above to-be quantified variable");

const typename Policy::pointer_type prune_target = policy.prune(children_fst);

if (prune_target.is_terminal()) {
if (req.data.source.is_nil()) {
return typename Policy::dd_type(prune_target.value());
}

const __quantify_recurse_in__output_terminal handler(aw, prune_target);
request_foreach(pq, req.target, handler);

continue;
} else if (prune_target.is_node()) {
quantify_request<0>::target_t rec(prune_target, Policy::pointer_type::nil());
const __quantify_recurse_in__forward handler(pq, rec);
request_foreach(pq, req.target, handler);

continue;
}
}
}

// -----------------------------------------------------------------------------------------
// CASE: Regular Level
// The variable should stay: proceed as in the Product Construction by simulating both
Expand Down Expand Up @@ -577,6 +607,37 @@ namespace adiar::internal
continue;
}

// -----------------------------------------------------------------------------------------
// CASE: Pruning Quantification
// Prune based on terminals for shallow to-be quantified variables dealt with during
// nested sweeping.
if constexpr (Policy::pruning_quantification) {
if (policy.should_prune()) {
adiar_assert(req.target.second().is_nil(),
"Pruning should only happen above to-be quantified variable");

const typename Policy::pointer_type prune_target = policy.prune(children_fst);

if (prune_target.is_terminal()) {
if (req.data.source.is_nil()) {
return typename Policy::dd_type(prune_target.value());
}

const __quantify_recurse_in__output_terminal handler(aw, prune_target);
request_foreach(pq_1, pq_2, req.target, handler);

Check warning on line 627 in src/adiar/internal/algorithms/quantify.h

View check run for this annotation

Codecov / codecov/patch

src/adiar/internal/algorithms/quantify.h#L626-L627

Added lines #L626 - L627 were not covered by tests

continue;

Check warning on line 629 in src/adiar/internal/algorithms/quantify.h

View check run for this annotation

Codecov / codecov/patch

src/adiar/internal/algorithms/quantify.h#L629

Added line #L629 was not covered by tests
} else if (prune_target.is_node()) {
quantify_request<0>::target_t rec(prune_target, Policy::pointer_type::nil());

const __quantify_recurse_in__forward handler(pq_1, rec);
request_foreach(pq_1, pq_2, req.target, handler);

continue;
}
}
}

// -----------------------------------------------------------------------------------------
// CASE: Regular Level
// The variable should stay: proceed as in the Product Construction by simulating both
Expand Down Expand Up @@ -962,6 +1023,11 @@ namespace adiar::internal
/// \brief Disable logic for partial quantification during sweep.
////////////////////////////////////////////////////////////////////////////////////////////////
static constexpr bool partial_quantification = false;

////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief Disable logic for pruning quantification during sweep.
////////////////////////////////////////////////////////////////////////////////////////////////
static constexpr bool pruning_quantification = false;
};

//////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -1071,6 +1137,11 @@ namespace adiar::internal
////////////////////////////////////////////////////////////////////////////////////////////////
static constexpr bool partial_quantification = false;

////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief Disable logic for pruning quantification during sweep.
////////////////////////////////////////////////////////////////////////////////////////////////
static constexpr bool pruning_quantification = false;

// bool has_sweep(typename Policy::label_type) const;

////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -1192,6 +1263,97 @@ namespace adiar::internal
//////////////////////////////////////////////////////////////////////////////////////////////////
// Multi-variable (predicate)

//////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief Policy Decorator for Pruning Quantification.
///
/// \details This is to-be used as the initial transposing sweep if (Repeated) Partial
/// Quantification is not to be used.
//////////////////////////////////////////////////////////////////////////////////////////////////
template <typename Policy>
class pruning_quantify_policy : public Policy
{
public:
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief Predicate for whether a level should be swept on (or not).
////////////////////////////////////////////////////////////////////////////////////////////////
using pred_t = predicate<typename Policy::label_type>;

private:
////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief Deepest level that needs to-be quantified.
////////////////////////////////////////////////////////////////////////////////////////////////
const typename Policy::label_type _deepest;

////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief Predicate for whether a level should be swept on (or not).
////////////////////////////////////////////////////////////////////////////////////////////////
const pred_t& _pred;

////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief Stores result of `_pred` to save on computation time
////////////////////////////////////////////////////////////////////////////////////////////////
bool _pred_result;

public:
////////////////////////////////////////////////////////////////////////////////////////////////
pruning_quantify_policy(const pred_t& pred, typename Policy::label_type deepest)
: _deepest(deepest)
, _pred(pred)
, _pred_result(false)
{}

////////////////////////////////////////////////////////////////////////////////////////////////
inline bool
should_quantify(typename Policy::label_type level)
{
const bool result = level == _deepest;
_pred_result = should_prune(level);
return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////
inline bool
should_prune(typename Policy::label_type level) const
{
return _pred(level) == Policy::quantify_onset;
}

inline bool
should_prune() const
{
return _pred_result;
}

////////////////////////////////////////////////////////////////////////////////////////////////
typename Policy::pointer_type
prune(const typename Policy::node_type::children_type &c) const
{
const typename Policy::pointer_type max_child = std::max(c[0], c[1]);

if (Policy::collapse_to_terminal(max_child)) {
// Collapse to terminal
return max_child;
}
if (max_child.is_terminal() && !Policy::keep_terminal(max_child)) {
// Non-collapsing and irrelevant, terminal. Skip to 'other'
return std::min(c[0], c[1]);
}

// Return 'nothing'
return Policy::pointer_type::nil();
}

////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief Enable partial quantification logic.
////////////////////////////////////////////////////////////////////////////////////////////////
static constexpr bool partial_quantification = false;

////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief Disable logic for pruning quantification during sweep.
////////////////////////////////////////////////////////////////////////////////////////////////
static constexpr bool pruning_quantification = true;
};

//////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief Policy Decorator for Partial Quantification.
///
Expand Down Expand Up @@ -1243,6 +1405,11 @@ namespace adiar::internal
/// \brief Enable partial quantification logic.
////////////////////////////////////////////////////////////////////////////////////////////////
static constexpr bool partial_quantification = true;

////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief Disable logic for pruning quantification during sweep.
////////////////////////////////////////////////////////////////////////////////////////////////
static constexpr bool pruning_quantification = false;
};

//////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -1405,13 +1572,14 @@ namespace adiar::internal

unreduced_t transposed;

// If transposition__max_iterations is 0, then only quantify the lowest level.
// If transposition__max_iterations is 0, then only quantify the lowest level (with pruning).
if (transposition__max_iterations == 0) {
// Singleton Quantification of bottom-most level
#ifdef ADIAR_STATS
stats_quantify.singleton_sweeps += 1u;
#endif
transposed = quantify<Policy>(ep, std::move(dd), label);
pruning_quantify_policy<Policy> pruning_impl(pred, label);
transposed = __quantify(ep, std::move(dd), pruning_impl);
} else {
// Partial Quantification
#ifdef ADIAR_STATS
Expand Down
Loading

0 comments on commit 17c49e3

Please sign in to comment.