#random #c-api #dsl

rvs

A library for defining and evaluating random variables using a simple DSL

5 releases (3 breaking)

0.5.0 Nov 26, 2020
0.4.1 Mar 19, 2018
0.4.0 Mar 18, 2018
0.3.0 Feb 1, 2018
0.2.0 Jan 8, 2018

#675 in Rust patterns

48 downloads per month
Used in 2 crates

MIT/Apache

74KB
2K SLoC

Rvs

Crates.io Build Status Codecov LoC Dependency Status

Rvs is a C API library for defining and evaluating random variables using a simple DSL (Domain Specific Language).

Examples

// An enumeration defintion with implicit value members.
enum Command {
    Read,
    Write,
    Erase,
}

// A variable that yields the repeating pattern: 2, 0, 1, 0
pattern = Pattern(
    Command::Erase,
    Command::Read,
    Command::Write,
    Command::Read,
);

// A variable that yields random values in the range [0, 7] inclusive
range = [0, 7];

// A variable that yields random values in the set {0, 1, 2}.  Yielded values
// are added back to the set.
sample_with_replacement = r{
    Command::Read,
    Command::Write,
    Command::Erase,
};

// A variable that yields random values in the set {0, 1, 2}.  Yielded values
// are removed from the set.  After all values have been yielded, the set is
// repopulated.
sample_without_replacement = {
    Command::Read,
    Command::Write,
    Command::Erase,
};

// A variable that yields weighted random values `0` 40% of the time, `1` 50%
// of the time, and `2` 10% of the time.
weighted_sample_with_replacement = r{
    40: Command::Read,
    50: Command::Write,
    10: Command::Erase,
};

// A variable that randomly yields values from a pool of 40 `0`s, 50 `1`s, and
// 10 `2`s.  Yielded values are removed from the pool.  The pool is
// re-populated after all values have been yielded.
weighted_sample_without_replacement = {
    40: Command::Read,
    50: Command::Write,
    10: Command::Erase,
};

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Feature Status

  • Expr features

    • next()
    • prev()
    • done()
    • reset()
    • Display
  • Parse from string

    • Parse from file
    • Parsing error reporting
    • Overriding existing variable definitions
  • C API

    • rvs_context_new()
    • rvs_context_free()
    • rvs_seed()
    • rvs_parse()
    • rvs_get()
    • rvs_next()
    • rvs_done()
    • rvs_prev()
    • rvs_reset()
    • rvs_write_definitions()
  • Grammar

    • Consructs
      • Variables
      • Enums
        • Implicit values E.g. enum Enum { Value, }
        • Explicit values E.g. enum Enum { Value = 0, }
        • Use of enum members E.g. enum Enum { Value = 0, } a = Enum::Value expands to a = 0
        • Use of enum types E.g. enum Enum { Value0, Value1, } a = Sample(Enum) expands to a = Sample(0, 1)
      • Structs
    • Types
      • Meta Types
        • Next - Returns the next value of a variable. Syntax: <identifier>
        • Copy - Returns a copy of a variable. Syntax: <identifier>.copy
        • Prev - Returns the last value of a variable. Syntax: <identifier>.prev
        • Done - Forces the sub expression to indicate done on every next. Syntax: <expr>.done
        • Once - Forces the sub expression to be evaluated once. Syntax: <expr>.once
        • Expand - Returns all evaluations of the expression until done. Syntax: Expand(<expr>) OR Expand(<expr>, <count-expr>)
      • Random Types
        • Range - Returns a random value in the range [, ] inclusive. Syntax: [<lower>, <upper>]
        • Weighted/non-weighted sampling with/without replacement
          • Weighted sampling with replacement. Syntax: r{<weight>: <expr>, ...}
            • Select new sub-expression only when current sub-expression is done
          • Non-weighted sampling with replacement. Syntax: r{<expr>, ...}
            • Select new sub-expression only when current sub-expression is done
          • Weighted sampling without replacement. Syntax: {<weight>: <expr>, ...}
            • Select new sub-expression only when current sub-expression is done
          • Non-weighted sampling without replacement. Syntax: {<expr>, ...}
            • Select new sub-expression only when current sub-expression is done
      • Misc Types
        • Pattern - Returns sub-expressions in order. Syntax: Pattern(<expr>, ...) * [x] Select new sub-expression only when current sub-expression is done
        • Loop/Sequence - Returns a sequnce of numbers. Syntax: Sequence(<count>) OR Sequence(<offset>, <count>) OR Sequence(<offset>, <increment>, <count>)
      • Operators
        • Arithmetic operators
          • +, -
          • *, /
          • %
        • Bitwise operators
          • &, |, ^
          • <<, >>
          • ~
        • Doneness for operators. Done when both operands have indicated done at least once.
    • Whitespace
    • Comments
    • Require/Include/Import/Etc
      • Import is idempotent
      • Search path - Key value pair E.g. 'key0=/a/b/c:key1=/d/e/f'.
        • Key relative paths E.g. ::key0::path::file => '/a/b/c/path/file.rvs'
        • Precendence path E.g. path::file => ['/a/b/c/path/file.rvs', '/d/e/f/path/file.rvs']
      • Source relative path E.g. a import fileb in filea becomes $(dirname filea)/fileb.rvs
      • Simplified naming E.g. path::file instead of 'path/file.rvs'
    • Filename in errors
    • Line numbers in errors

Extra

  • Optimizations
  • Separate into multiple crates
    • Rvs Library - rvs
    • DSL (Grammar/Parser, AST) - rvs-parser
    • Interactive binary - rvs-repl
    • C-API - rvs-capi
  • Implement the Iterator trait
  • Use released version of rand
  • Use monomorphized Rng instead of a trait object. Can make generic or a type.
  • Add source information to transform errors

Dependencies

~0.8–1.1MB
~19K SLoC