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
//! ポテンシャル関数。
use super::binop;
pub use binop::{CommutativeGroup, Magma};
/// ポテンシャル関数。
pub trait PotentialFunction {
/// 要素の型。
type Item: CommutativeGroup;
/// 要素数 $n$ の集合 $\\{0, 1, \\dots, n-1\\}$ で初期化する。
fn new(n: usize, cgroup: Self::Item) -> Self;
/// 集合の要素数 $n$ を返す。
fn len(&self) -> usize;
/// 集合が空であれば `true` を返す。
fn is_empty(&self) -> bool { self.len() == 0 }
/// ポテンシャルの差を定義する。
///
/// $\\phi(x\_u)-\\phi(x\_v) = w$ とする。
///
/// 呼び出し前の定義と矛盾しない場合、呼び出し前に $\\phi(x\_u)-\\phi(x\_v)$ が未定義なら
/// `Ok(true)` を、そうでなければ `Ok(false)` を返す。
/// 矛盾する場合、定義は変化せずに `Err(e)` を返す。ただし、`e`
/// は呼び出し前の $\\phi(x\_u) - \\phi(x\_v)$ を表す。
fn relate(
&mut self,
u: usize,
v: usize,
w: <Self::Item as Magma>::Set,
) -> Result<bool, <Self::Item as Magma>::Set>;
/// ポテンシャルの差を求める。
///
/// $\\phi(x\_u)-\\phi(x\_v) = w$ であれば `Some(w)` を返す。
/// 未定義ならば `None` を返す。
fn diff(&self, u: usize, v: usize) -> Option<<Self::Item as Magma>::Set>;
/// 代表元とのポテンシャルの差を求める。
fn repr_diff(&self, u: usize) -> (usize, <Self::Item as Magma>::Set);
}