Struct Chain

Source
pub struct Chain<T, M: Map<T> = BTree> { /* private fields */ }
Expand description

A Markov chain.

This type implements Serialize and Deserialize when the serde feature is enabled (which it is by default).

Implementations§

Source§

impl<T, M: Map<T>> Chain<T, M>

Source

pub fn new(depth: usize) -> Self

Creates a new chain.

See Self::depth for an explanation of the depth.

Examples found in repository?
examples/example.rs (line 23)
19fn main() -> io::Result<()> {
20    const DEPTH: usize = 6;
21    // Maps each sequence of 6 items to a list of possible next items.
22    // `HashChain` uses hash maps internally; b-trees can also be used.
23    let mut chain = HashChain::new(DEPTH);
24
25    // In this case, corpus.txt contains one paragraph per line.
26    let file = File::open("examples/corpus.txt")?;
27    let mut reader = BufReader::new(file);
28    let mut line = String::new();
29    // The previous `DEPTH` characters before `line`.
30    let mut prev = Vec::<char>::new();
31
32    while let Ok(1..) = reader.read_line(&mut line) {
33        // `Both` means that the generated random output could start with the
34        // beginning of `line` or end after the end of `line`.
35        chain.add_all(line.chars(), AddEdges::Both);
36
37        // This makes sure there's a chance that the end of the previous line
38        // could be followed by the start of the current line when generating
39        // random output.
40        chain.add_all(
41            prev.iter().copied().chain(line.chars().take(DEPTH)),
42            AddEdges::Neither,
43        );
44
45        if let Some((n, (i, _c))) =
46            line.char_indices().rev().enumerate().take(DEPTH).last()
47        {
48            // Keep only the most recent `DEPTH` characters.
49            prev.drain(0..prev.len().saturating_sub(DEPTH - n - 1));
50            prev.extend(line[i..].chars());
51        }
52        line.clear();
53    }
54
55    // Generate and print random Markov data.
56    let mut stdout = BufWriter::new(io::stdout().lock());
57    let mut prev_newline = false;
58    for &c in chain.generate() {
59        if prev_newline {
60            writeln!(stdout)?;
61        }
62        prev_newline = c == '\n';
63        write!(stdout, "{c}")?;
64    }
65    stdout.flush()
66}
Source

pub fn depth(&self) -> usize

Gets the chain’s depth.

A depth of n means the chain maps sequences of n items of type T to a list of possible next items.

Source

pub fn add_all<I>(&mut self, items: I, edges: AddEdges)
where I: IntoIterator<Item = T>, T: Clone,

Adds all items in an iterator to the chain.

This essentially calls Self::add on every overlapping window of self.depth() elements plus the item following each window. (Smaller windows at the start of the sequence may also be added depending on the value of edges.)

edges controls whether the start or end of items may be used as the start or end of a generated sequence from the chain. See the documentation for AddEdges for more information.

Examples found in repository?
examples/example.rs (line 35)
19fn main() -> io::Result<()> {
20    const DEPTH: usize = 6;
21    // Maps each sequence of 6 items to a list of possible next items.
22    // `HashChain` uses hash maps internally; b-trees can also be used.
23    let mut chain = HashChain::new(DEPTH);
24
25    // In this case, corpus.txt contains one paragraph per line.
26    let file = File::open("examples/corpus.txt")?;
27    let mut reader = BufReader::new(file);
28    let mut line = String::new();
29    // The previous `DEPTH` characters before `line`.
30    let mut prev = Vec::<char>::new();
31
32    while let Ok(1..) = reader.read_line(&mut line) {
33        // `Both` means that the generated random output could start with the
34        // beginning of `line` or end after the end of `line`.
35        chain.add_all(line.chars(), AddEdges::Both);
36
37        // This makes sure there's a chance that the end of the previous line
38        // could be followed by the start of the current line when generating
39        // random output.
40        chain.add_all(
41            prev.iter().copied().chain(line.chars().take(DEPTH)),
42            AddEdges::Neither,
43        );
44
45        if let Some((n, (i, _c))) =
46            line.char_indices().rev().enumerate().take(DEPTH).last()
47        {
48            // Keep only the most recent `DEPTH` characters.
49            prev.drain(0..prev.len().saturating_sub(DEPTH - n - 1));
50            prev.extend(line[i..].chars());
51        }
52        line.clear();
53    }
54
55    // Generate and print random Markov data.
56    let mut stdout = BufWriter::new(io::stdout().lock());
57    let mut prev_newline = false;
58    for &c in chain.generate() {
59        if prev_newline {
60            writeln!(stdout)?;
61        }
62        prev_newline = c == '\n';
63        write!(stdout, "{c}")?;
64    }
65    stdout.flush()
66}
Source

pub fn add<I>(&mut self, items: I, next: Option<T>)
where I: IntoIterator<Item = T>,

Adds items to the chain.

If items yields at least self.depth() items, this increases the chance that the first self.depth() items will be followed by next in a generated sequence (additional items in items are ignored).

If items yields fewer than self.depth() items, this method increases the chance that those items, when they are the only items that have been generated so far in a sequence (i.e., the start of a sequence), will be followed by next. In the case where items yields no elements, this increases the chance that item will be produced as the first element of a generated sequence.

If next is None, this method increases the chance that items will be considered the end of a sequence.

Source

pub fn generate(&self) -> Generator<'_, T, ThreadRng, M>

Available on crate feature std only.

Generates random Markov chain data.

Returns an iterator that yields the elements by reference. If you want them by value, simply use Iterator::cloned (as long as T is Clone).

Examples found in repository?
examples/example.rs (line 58)
19fn main() -> io::Result<()> {
20    const DEPTH: usize = 6;
21    // Maps each sequence of 6 items to a list of possible next items.
22    // `HashChain` uses hash maps internally; b-trees can also be used.
23    let mut chain = HashChain::new(DEPTH);
24
25    // In this case, corpus.txt contains one paragraph per line.
26    let file = File::open("examples/corpus.txt")?;
27    let mut reader = BufReader::new(file);
28    let mut line = String::new();
29    // The previous `DEPTH` characters before `line`.
30    let mut prev = Vec::<char>::new();
31
32    while let Ok(1..) = reader.read_line(&mut line) {
33        // `Both` means that the generated random output could start with the
34        // beginning of `line` or end after the end of `line`.
35        chain.add_all(line.chars(), AddEdges::Both);
36
37        // This makes sure there's a chance that the end of the previous line
38        // could be followed by the start of the current line when generating
39        // random output.
40        chain.add_all(
41            prev.iter().copied().chain(line.chars().take(DEPTH)),
42            AddEdges::Neither,
43        );
44
45        if let Some((n, (i, _c))) =
46            line.char_indices().rev().enumerate().take(DEPTH).last()
47        {
48            // Keep only the most recent `DEPTH` characters.
49            prev.drain(0..prev.len().saturating_sub(DEPTH - n - 1));
50            prev.extend(line[i..].chars());
51        }
52        line.clear();
53    }
54
55    // Generate and print random Markov data.
56    let mut stdout = BufWriter::new(io::stdout().lock());
57    let mut prev_newline = false;
58    for &c in chain.generate() {
59        if prev_newline {
60            writeln!(stdout)?;
61        }
62        prev_newline = c == '\n';
63        write!(stdout, "{c}")?;
64    }
65    stdout.flush()
66}
Source

pub fn generate_with_rng<R: Rng>(&self, rng: R) -> Generator<'_, T, R, M>

Like Self::generate, but takes a custom random number generator.

Source

pub fn get<'a, B>(&'a self, items: &[B]) -> Option<&'a T>
where B: Borrow<T>,

Available on crate feature std only.

Gets a random item that has followed items in the added data.

If items yields more than self.depth() items, only the first self.depth() items are considered. If items yields fewer than self.depth() items (potentially zero), those items are interpreted as the beginning of a generated sequence.

Source

pub fn get_with_rng<'a, B, R>(&'a self, items: &[B], rng: R) -> Option<&'a T>
where B: Borrow<T>, R: Rng,

Like Self::get, but takes a custom random number generator.

Trait Implementations§

Source§

impl<T: Clone, M: Map<T>> Clone for Chain<T, M>

Source§

fn clone(&self) -> Self

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: Debug, M: Map<T>> Debug for Chain<T, M>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de, T, M> Deserialize<'de> for Chain<T, M>
where T: Deserialize<'de>, M: Map<T>,

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl<T, M> Serialize for Chain<T, M>
where T: Serialize, M: Map<T>,

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<T, M> Freeze for Chain<T, M>
where <M as MapFromSlice<T>>::To<Box<FrequencyMap<T, M>>>: Freeze,

§

impl<T, M> RefUnwindSafe for Chain<T, M>
where <M as MapFromSlice<T>>::To<Box<FrequencyMap<T, M>>>: RefUnwindSafe, T: RefUnwindSafe,

§

impl<T, M> Send for Chain<T, M>
where <M as MapFromSlice<T>>::To<Box<FrequencyMap<T, M>>>: Send, T: Send,

§

impl<T, M> Sync for Chain<T, M>
where <M as MapFromSlice<T>>::To<Box<FrequencyMap<T, M>>>: Sync, T: Sync,

§

impl<T, M> Unpin for Chain<T, M>
where <M as MapFromSlice<T>>::To<Box<FrequencyMap<T, M>>>: Unpin, T: Unpin,

§

impl<T, M> UnwindSafe for Chain<T, M>
where <M as MapFromSlice<T>>::To<Box<FrequencyMap<T, M>>>: UnwindSafe, T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,