1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
//! This module representes the values that can be put inside a segment tree,
//! the summaries that you can receive from a query about a segment in the segment tree,
//! and the actions that you can perform on the segment tree.
//!
//! In order for a choice of types for `Value`, `Summary` and `Action`, to work
//! in a segment tree, they must be an instance of the [`Data`] trait.
//!
//! In addition, this module provides the [`SizedSummary`] and [`Keyed`] traits,
//! and some common possible instantiations in the [`example_data`] module.
pub mod example_data;
pub use example_data::{Keyed, SizedSummary};
use std::ops::Add;
/// This trait represents the data that will be stored inside the tree.
///
/// Every node in the tree will contain an action to be performed on the node's subtree,
/// a summary of the node's subtree, and a value.
/// The action will be of type [`Self::Action`], the summary of type [`Self::Summary`], and the value will be of type [`Self::Value`].
///
/// * [`Self::Value`] is the type of values in your tree, which can be anything at all. The tree
/// representes a sequence of values of type [`Self::Value`].
///
/// * [`Self::Summary`] can include: indices, sizes, sums, maximums
/// and minimums of subtrees, and more. It is the type of information you can gather about a subsegment
/// of your tree. This is the result of querying for information about a segment.
///
/// * [`Self::Action`] is the type of actions that can be performed on subsegments. for example,
/// reverse a subsegment, add a constant to all values in a subsegment, apply `max` with a
/// constant on all values in a subsegment, and so on.
///
/// All of the trait's requirements are modeled as separated traits in order to allow for easier
/// mixing and matching of different values, summaries and actions.
///
/// For convenience, `(Value, Summary Action)` implements the `Data` trait by itself
/// if the types are compatible, so you don't need to create a new market type if you don't want to.
///
/// # Requirements
///
/// In order for everything to work, we must know how to:
/// * Compose actions together:
/// > Action composition is done by an [`Add`] instance.
/// > i.e., applying `a + b` should be equivalent to applying `b` and then applying `a`.
/// > Composition is right to left. What chronologically happens first, is on the right.
///
/// * Compute the summary of a single value, and add up summaries of two subsegments together:
/// > Summaries of segments are created by converting single values into their singletone.
/// > summaries using `to_summary()`, and summaries can be added together to obtain bigger summaries, using an
/// > [`Add`] instance. i.e.,
/// > if the summary for a list `vals_list1` is `summary1`, and the summary for a list `vals_list2`
/// > is `summary2`, the summary of the concatenation `vals_list1 + vals_list2` should be `summary1 + summary2`.
///
/// * Apply an action on a single value, and apply an action on a summary of a segment:
/// > Applying actions on values and on summaries is required by the bounds
/// > [`Self::Action`]`: `[`Acts`]`<`[`Self::Value`]`> + `[`Acts`]`<`[`Self::Summary`]`>`.
/// > This means that in order to update a segment summary `summary: `[`Self::Summary`] after
/// > action `action: `[`Self::Action`] has been applied to it,
/// > you could execute `summary = action.act(summary);` or `action.act_inplace(&mut summary);`,
/// > and similarly as well for [`Self::Value`].
///
/// Additional requirements:
/// * Decide whether to reverse the subsegment it is acted upon. This is done by implementing the
/// [`Action::to_reverse()`] function. If you do not want to reverse segments, you can use the default implementation,
/// which always returns false.
/// * Have an identity action and empty summary: These are represented by the bounds [`Self::Action`]`: `[`Default`],
/// [`Self::Summary`]`: `[`Default`].
/// * Test actions for being the identity. This is represented by [`Action::is_identity()`].
///
/// # Rules
/// In order for the segment trees to work correctly, all of these operations must play nicely with each other.
/// Most of the rules are imposed in the documentation of the [`Action`] trait. In addition, any instance must
/// obey these rules:
///
/// * Summary addition must be associative, so that we get the same summary regardless of the tree structure,
/// and the empty summary must be the identity.
/// ```notrust
/// (summary1 + summary2) + summary3 === summary1 + (summary2 + summary3)
/// default() + summary === summary + default() === summary
/// ```
///
pub trait Data {
/// The values that reside in trees.
type Value: ToSummary<Self::Summary>;
/// The summaries of values over segments. When querying a segment,
/// you get a summary of the segment, represented by a value of type `Self::Summary`.
type Summary: Copy + Default + Add<Output = Self::Summary>;
/// The actions you can perform on the values
type Action: Action + Acts<Self::Value> + Acts<Self::Summary>;
}
/// A [`Data`] implementation for a generic triplet of value, summary and action types,
/// so you don't have to make an `impl` yourself.
impl<V, S, A> Data for (V, S, A)
where
V: ToSummary<S>,
S: Copy + Default + Add<Output = S>,
A: Action + Acts<V> + Acts<S>,
{
type Value = V;
type Summary = S;
type Action = A;
}
/// Trait representing actions. this entailes having an identity action ([`Default`]), being able to compose actions
/// ([`Add`]`<Output=Self>`), checking whether an action is the identity action, and checking whether this action
/// reverses subsegments.
/// In order for the segment trees to work correctly, all of the operations must play nicely with each other.
/// In particular, it must obey these rules:
///
/// # Rules
/// * composition of actions: action composition must be associative, and the
/// identity action should actually be the identity.
/// ```notrust
/// (action3 + action2) + action1 === action3 + (action2 + action1)
/// default() + action === action + default() === action
/// ```
///
/// If the action implements `Acts<Summary>` for some type `Summary` or `Value`:
/// * Action composition must actually be action composition, and the identity must actually be the identity.
/// ```notrust
/// (action2 + action1).act(value) == action2.act(action1.act(value))
/// (action2 + action1).act(summary) == action2.act(action1.act(summary))
/// default().act(value) === value
/// default().act(summary) === summary
/// ```
///
/// * Adding up summaries and then applying an action must be equal to applying the
/// action separately and then summing the parts:
/// ```notrust
/// action.act(summary1 + summary2) == action.act(summary1) + action.act(summary2)
/// ```
/// This property is used so that the summary values can be updated without
/// updating the whole tree.
/// This means that the action respects the monoid structure of the summaries.
///
/// * If the action reverses segments, (i.e, if `D::to_reverse(action) == true`), then it has to satisfy a 'cross'
/// a cross version instead:
/// ```notrust
/// action.act(summary1 + summary2) == action.act(summary2) + action.act(summary1)
/// ```
///
/// And it should also satisfy that composing two actions
/// xor's their [`Action::to_reverse()`] results:
/// ```notrust
/// (action2 + action1).to_reverse() === action2.to_reverse() ^ action1.to_reverse()
/// ```
///
/// * The action should respect [`ToSummary::to_summary()`]:
/// ```notrust
/// action.act(value).to_summary() === action.act(value.to_summary())
/// ```
///
pub trait Action: Copy + Default + Add<Output = Self> {
/// Test whether this action is the identity action.
fn is_identity(self) -> bool;
/// This function should be implemented if you want to be able to reverse subsegments of your tree.
/// The default implementation always returns `false`.
///
/// This function should return whether this action reverses the segment it is applied to.
fn to_reverse(self) -> bool {
false
}
}
/// Trait representation actions on a type `V`. If `A: Acts<V>` that means that given any `action: A`,
/// we can apply it to any `val: V`. This trait is used to represent the actions on
/// values and summaries used by segment trees.
///
/// Morally `Action` should be a supertrait of this trait.
pub trait Acts<V> {
/// Act on a value in-place.
fn act_inplace(&self, object: &mut V);
/// Act on a value and return the result.
fn act(&self, mut object: V) -> V {
self.act_inplace(&mut object);
object
}
}
/// This trait is implemented by Values,
/// and provides a conversion from a value to the summary of that single value.
pub trait ToSummary<S> {
/// Creates the summary of a single value.
fn to_summary(&self) -> S;
}