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.
There are two PQL algorithms - randomized, and exhaustive.
Here is the Randomized PQL Algorithm in a nutshell, followed by a detailed description of each step.
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.
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 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.
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".
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".
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.
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 ..."
Here is the Exhaustive PQL Algorithm. At the moment, it only supports all-in equity queries.