Markov

Struct Markov 

Source
pub struct Markov { /* private fields */ }
Expand description

The Markov chain generator

  1. Initialize it empty or from saved corpus
  2. Add data to complete the corpus
  3. Generate results

Implementations§

Source§

impl Markov

Source

pub fn new() -> Markov

Creates an empty Markov instance

use markov_strings::*;

let mut markov = Markov::new();
Source

pub fn from_export(export: ImportExport) -> Markov

Creates a Markov instance from previously imported data

See Markov::export() for more information.

Example: load your saved corpus from a flat file with the bincode crate.

let file = File::open("dumped.db").unwrap();
let reader = BufReader::new(file);
let data = bincode::deserialize_from(reader).unwrap();
let mut markov = Markov::from_export(data);
Source

pub fn set_state_size(&mut self, size: usize) -> Result<&mut Self, ErrorType>

Sets the “state size” of your Markov generator.

The result chain is made up of consecutive blocks of words, and each block is called a state. Each state is itself made up of one (1) or more words.

let data: Vec<InputData> = vec![];
let mut markov = Markov::new();

// We _must_ set the state_size before adding data...
assert!(markov.set_state_size(3).is_ok());

// ...or it will return an error
markov.add_to_corpus(data);
assert!(markov.set_state_size(4).is_err());
  • A state size of 1 word will mostly output non-sense gibberish.
  • A state size of 2 words can produce interesting results, when correctly filtered.
  • A state size of 3 or more words will produce more intelligible results, but you’ll need a source material that will allow it while staying random enough.

! You CANNOT change the state_size once you’ve added data with Markov::add_to_corpus().
The internal data structure is reliant on the state size, and it cannot be changed without rebuilding the whole corpus.

Default value 2.

Source

pub fn add_to_corpus(&mut self, data: Vec<InputData>)

Adds data to your Markov instance’s corpus.

This is an expensive method that can take a few seconds, depending on the size of your input data. For example, adding 50.000 tweets while running on fairly decent computer takes more than 20 seconds.

To avoid rebuilding the corpus each time you want to generate a text, you can use Markov::export() and Markov::from_export()

You can call .add_to_corpus() as many times as you need it.

Source

pub fn set_filter(&mut self, f: fn(&MarkovResult) -> bool) -> &mut Self

Sets a filter to ensure that outputted results match your own criteria.

A good filter is essential to get interesting results out of Markov::generate(). The values you should check at minimum are the MarkovResult.score and MarkovResult.refs’ length.

The higher these values, the “better” the results. The actual thresholds are entierely dependant of your source material.

let mut markov = Markov::new();
// We're going to generate tweets, so...
markov
    .set_filter(|r| {
        // Minimum score and number of references
        // to ensure good randomness
        r.score > 50 && r.refs.len() > 10
            // Max length of a tweet
            && r.text.len() <= 280
            // No mentions
            && !r.text.contains("@")
            // No urls
            && !r.text.contains("http")
  });
Source

pub fn unset_filter(&mut self) -> &mut Self

Removes the filter, if any

let mut markov = Markov::new();
// Those two lines a functionally identical.
markov.set_filter(|r| true);
markov.unset_filter();
Source

pub fn set_max_tries(&mut self, tries: u16) -> &mut Self

Sets the maximum number of times the generator will try to generate a result.

If Markov::generate fails [max_tries] times to generate a sentence, it returns an ErrorType.TriesExceeded.

Default value: 100

Source

pub fn generate(&self) -> Result<MarkovResult, ErrorType>

Generates a random result from your corpus.

let mut markov = Markov::new();
let data: Vec<InputData> = vec![/* lots of data */];
markov.add_to_corpus(data);
let result = markov.generate().unwrap();
Source

pub fn get_input_ref(&self, index: usize) -> Option<&InputData>

Gets an item from the original data.

Use this with the indices from MarkovResult.refs

let data: Vec<InputData> = vec![
  InputData{ text: "foo bar lorem ipsum".to_string(), meta: Some("something".to_string()) },
];
let mut markov = Markov::new();
markov.add_to_corpus(data);
let result = markov.generate().unwrap();

// Since we only have 1 string in our corpus, we have 1 ref...
let mut expected: Vec<usize> = vec![];
expected.push(0);
assert_eq!(result.refs, expected);
let input_ref = *result.refs.get(0).unwrap();
assert_eq!(markov.get_input_ref(input_ref).unwrap().text, "foo bar lorem ipsum");
assert_eq!(markov.get_input_ref(input_ref).unwrap().meta, Some("something".to_string()));
Source

pub fn export(self) -> ImportExport

Exports the corpus into a serializable structure.

The Markov::add_to_corpus() method being expensive, you may want to build your corpus once, then export it to a serializable file file for later use.

let data: Vec<InputData> = vec![];
let mut markov = Markov::new();
markov.add_to_corpus(data);
let export = markov.export();

let markov = Markov::from_export(export);
let result = markov.generate();

Trait Implementations§

Source§

impl<'de> Deserialize<'de> for Markov

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 Serialize for Markov

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 Freeze for Markov

§

impl RefUnwindSafe for Markov

§

impl Send for Markov

§

impl Sync for Markov

§

impl Unpin for Markov

§

impl UnwindSafe for Markov

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> 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, 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>,