# Odds Oracle (PQL) Runtime Model

The Odds Oracle is at its core a simulation engine. Whenever using simulation software to approximate the real-world, it is important to understand exactly how the simulations are performed. Below is an outline of the core PQL algorithms which power the Odds Oracle.

## The Core PQL Algorithms

There are two PQL algorithms - randomized, and exhaustive.

### Randomized (Monte-Carlo) PQL Algorithm

Here is the Randomized PQL Algorithm in a nutshell, followed by a detailed description of each step.

• Repeat N times (N = 600,000 by default)
• Pick a random hand for each player (and board if a flop game)
• If any card appears in more than one place, go back one step and try again
• Complete the hands and board with random cards as needed
• If there is a PQL "where" clause:
• If where clause evaluates to false, go back to "Pick a random hand" step
• Gather data (evaluate selectors)

#### "Repeat N Times"

The core of any monte-carlo algorithm, poker or otherwise, is the same: generate a bunch of random data and gather statistics. The larger the number of trials, the more accurate your results will be. As with any random process, however, increasing the number of trials has diminishing returns - informally speaking, to get twice as accurate you need four times as many trials.

#### "Pick a random hand for each player (and board if a flop game)"

Suppose we are racing "AA" vs. "AxKx" on a board of "KcJdJh". We simply pick a random set of cards from each range. For instance, player one might get "AsAh", and player two might get "AdKd".

#### "If any card appears in more than one place, go back one step and try again"

If we are racing "AA" vs. "AxKx" and pick "AsAh" for player one and "AsKs" for player two, we have a duplicated card and must pick the random hands again. Note that in general, we cannot simply replace the first hand with a duplicated card, as this can result in generating hands with the wrong probability.

#### "Complete the hands and board with random cards as needed"

Continuing with our "AA" vs. "AxKx" on board "KcJdJh" example - if we chose "AsAh" vs "AdKd", then we could pick random cards "2s5d" to complete the board "KcJdJh2s5d". In a seven-card stud game, we might have picked a random hand "AsKsJd2c3s" and need to add two random cards to complete the hand "AsKsJd2c3s5d8d".

#### "If there is a PQL 'where' clause:" (Odds Oracle "Require that")

The PQL "where" clause allows us to only consider situations where certain properties hold. This only applies to custom PQL queries and Odds Oracle queries that use "Require that".

##### "If where clause evaluates to false, go back to 'Pick a random hand' step

Suppose we have the following PQL query: "select avg(riverEquity(p1)) from game='holdem', p1='KsJs', p2='8d8h' where handtype(p1, flop) >= flush". If the board reads "Ts8s7h2d5d", then the where clause is false because p1 does not have a flush or better on the flop - in this case, we start over picking random hands and board. If the board reads "2s5s7s9cTc", then the where clause is true an we can proceed.

#### Gather data (PQL: evaluate selectors)

If we made it this far, we now have a legal set of random hands (and completed board), and the (optional) where clause is true - now we can gather our statistical data point. In the Odds Oracle, this data could be part of a graph, "Equity Stats", or any number of custom questions. In PQL, data is collected by selectors (for instance, "flopHandType" and "avgEquity" in "select handtype(p1, flop) as flopHandType, avg(riverEquity(p1)) as avgEquity ..."

### Exhaustive (Exact) PQL Algorithm

Here is the Exhaustive PQL Algorithm. At the moment, it only supports all-in equity queries.

• For every possible legal combination of hands (and board cards):
• Gather data (evaluate selectors)