PREM

The Physical Randomness Experiment Modeler

Documentation

Interface

PREM is a probability calculator inspired by AnyDice. If you've used that tool, much of PREM will be familiar to you. If not, just know that PREM can tell you the likelihood of each possible outcome of random events like card draws and dice rolls.

How to use PREM

PREM generates output when it reads an output statement, such as:

output 2d6

The expression after the output keyword tells PREM what to compute the results of. In this case, we ask for the result of 2d6, or two traditional 6-sided dice.

PREM gives each output a default name: output 1, output 2, and so on. For more descriptive names, we can use the as keyword to rename an output:

output 2d6 as "Two dice"

Data Types

Numbers

Currently, PREM only supports whole numbers in the input. Division is on the roadmap, and will enable all rational numbers when it implemented.

Sequences

A Sequence is a comma-separated list wrapped in curly braces. Any non-number elements in a sequence will be converted into Sequences and flattened, such that the following statements are equivalent:

output { 1d4, { 5, 6 }, 7 }
output { 1, 2, 3, 4, 5, 6, 7 }

Dice

Dice expressions in PREM use a syntax popular in tabletop RPGs; the number of dice to roll is followed by the letter 'd', then the number of faces on the die. For example, a roll of two six-sided dice is expressed as 2d6. If no number is provided for the quantity of dice, one die is assumed, such that the following statements are equivalent:

output d20
output 1d20
Arbitrary Dice

We can define arbitrary dice by replacing the number of faces with a sequence of faces the die should have:

output d{ 1, 2, 5 } as "Monty Python's d5"
Composing Dice Expressions

Dice expressions are evaluated left to right, so composing them results in dependent rolls. Take for example the expression 2d2d6. PREM first computes the possible results of 2d2. Then for each result ({ 2, 3, 3, 4 }), computes the result of rolling that many d6. Consequently, the following are equivalent:

output 2d2d6
output { 2, 3, 3, 4 }d6
output { 2d6, 3d6, 3d6, 4d6 }

This can be overriden using parentheses. Expressions in parentheses are evaluated first, just like in math. Consequently, the following are equivalent:

output 2d(2d6)
output 4d6
        

Cards

Cards expressions look a lot like Dice expressions, except we use a 'c' instead of a 'd'

output 1c3 as "Blind 3-Card Monty"

Like with dice, we can omit the quantity to draw just one card from the deck.

output c3 as "Still a blind 3-Card Monty"
Arbitrary Decks

We can draw from a deck of arbitrary cards by replacing the Number after the 'c' with a Sequence. For each Number in the Sequence, the deck will have one card whose value is that Number.

output 2c{ 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13 } as "2 face cards"
Composing Card Expressions

Card expressions are evaluated left to right, so composing them results in dependent draws. Take for example the expression 2c2c6. PREM first computes the possible results of 2c2. Then for each result ({ 3, 3 }), computes the result of drawing that many cards from a deck of 6. Consequently, the following are equivalent:

output 2c2c6
output { 3, 3 }c6
output 3c6

Like with dice, we can override this behavior with parentheses:

output 2c(3c6) as "choose 2 cards at random from a hand of 3 drawn from a deck of 6."
Shuffling Cards

When drawing more cards than are present in a deck, the deck is shuffled when emptied. Drawing then resumes until the specified number of cards are drawn.

output 4c3 as "Draw all 3 cards, shuffle, then draw 1 more card."

Type Coersion

Expecting a Number

Dice and Cards are evaluated to a Sequence of their possible results, then coerced as a Sequence. When a Sequence is provided, the expression is evaluated for each Number in the Sequence, and the results are merged into a single Sequence.

Expecting a Sequence

A Number is transformed into a Sequence containing only that Number. Dice and Cards are evaluated to a Sequence of their possible results.

Expecting Dice

A Number is treated as a die that can only roll that Number. A Sequence is treated as a die with a face displaying each Number in the Sequence. Cards are evaluated to a Sequence of their possible results, then coerced as a Sequence.

Expecting Cards

A Number is treated as a single card with a value of that Number. A Sequence is treated as a deck with a card displaying each Number in the Sequence. Dice are evaluated to a Sequence of their possible results, then coerced as a Sequence.

Boolean Logic

Not

The Not operator is written as a ! in PREM. It changes a 0 value to a 1, and any non-zero value to a 0.

output !2 as "0"
output !1 as "0"
output !0 as "1"
output !-1 as "0"

When applied to a Sequence, Cards, or Dice, this operator affects each value in the resulting Sequence.

output !{-1, 0, 1} as "0, 1, 0"

Comparisons

The following comparison operators express the relationship between two numbers. The result is 1 if the indicated relationship is true, and 0 otherwise.

Comparison Operator Examples
Less Than <
output 1 < 2 as "1"
output 2 < 2 as "0"
output 3 < 2 as "0"
Less Than or Equal <=
output 1 <= 2 as "1"
output 2 <= 2 as "1"
output 3 <= 2 as "0"
Greater Than <
output 1 > 2 as "0"
output 2 > 2 as "0"
output 3 > 2 as "1"
Greater Than or Equal &lgt;=
output 1 >= 2 as "0"
output 2 >= 2 as "1"
output 3 >= 2 as "1"
Equal &lgt;=
output 1 == 2 as "0"
output 2 == 2 as "1"
output 3 == 2 as "0"
Not Equal !=
output 1 != 2 as "1"
output 2 != 2 as "0"
output 3 != 2 as "1"

Each value in a Sequence, Dice, or Cards is compared separately, and the results are collected into a new Sequence.

output d2 == d2 as "{0, 0, 1, 1}"

Order of Operations

PREM obeys the following order of operations, moving from left to right at each step:

  1. Parentheses
  2. Not
  3. Less Than, Greater Than, Less Than or Equal, Greater Than or Equal
  4. Equal, Not Equal
output 1 - 2 * 3 as "-5"

Arithmetic

Negative Numbers

Negative numbers are written the same way in PREM as in everyday life: -42.

Negating stuff in parentheses also works the way you would expect:

output -(-42) as "42"

Negating Dice, Cards, or a Sequence negates each element of the result:

output -1d6 as "{-6, -5, -4, -3, -2, -1}"
output -{-1, 2, -3} as "{1, -2, 3}"

Math Operators

PREM allows you to multiply numbers using the * operator, and divide with /. You can also add and subtract with + and -, respectively.

For ordinary math, this looks like you'd expect:

output 2 * 2 as "4"
output 3/4 as "0.75"
output 1+1 as "2"
output 6 - 9 as "-3"

Mathematical operations distribute across Sequences, Dice, or Cards like this:

output 3 * {1, 2, 3} as "{3, 6, 9}"

You can also operate on two Sequences, Dice, or Cards to get the result of applying the operator to all possible pairs:

output {1, 2} * {1, 2, 3} as "{1, 2, 3, 2, 4, 6}"

You can get the remainder of a division by using the % modulo operator, like so:

output {1, 2, 3} % 1d2 as "{0, 1, 0, 0, 1, 0}"

Order of Operations

PREM obeys the following mathematical order of operations, moving from left to right at each step:

  1. Parentheses
  2. Negation
  3. Multiplication, Division, and Modulo
  4. Addition and Subtraction
output 1 - 2 * 3 as "-5"

version 1.0

Created by Tabris Thomas