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 52a74f3 commit b6b5783
Showing 1 changed file with 161 additions and 2 deletions.
163 changes: 161 additions & 2 deletions src/adiar/internal/algorithms/quantify.h
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,32 @@ 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()) {
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 +603,33 @@ 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()) {
const __quantify_recurse_in__output_terminal handler(aw, prune_target);
request_foreach(pq_1, pq_2, req.target, handler);

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

View check run for this annotation

Codecov / codecov/patch

src/adiar/internal/algorithms/quantify.h#L618-L619

Added lines #L618 - L619 were not covered by tests

continue;

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

View check run for this annotation

Codecov / codecov/patch

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

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

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

View check run for this annotation

Codecov / codecov/patch

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

Added line #L623 was not covered by tests

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

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

View check run for this annotation

Codecov / codecov/patch

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

Added lines #L625 - L626 were not covered by tests

continue;

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

View check run for this annotation

Codecov / codecov/patch

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

Added line #L628 was not covered by tests
}
}
}

// -----------------------------------------------------------------------------------------
// CASE: Regular Level
// The variable should stay: proceed as in the Product Construction by simulating both
Expand Down Expand Up @@ -962,6 +1015,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 +1129,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 +1255,96 @@ 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)) {
return max_child;
}
if (max_child.is_terminal()) {
// Must be non-collapsing, i.e. irrellevant, terminal. Return '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 +1396,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 +1563,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

0 comments on commit b6b5783

Please sign in to comment.