Poker Query Language Overview
What is PQL?
PQL is a language meant for people who want to ask poker probability
questions. It is the core engine that powers the Odds Oracle and propokertools.com.
What kinds of questions can PQL answer?
All kinds of questions.
Can you give an example?
Sure. If we want to know the average all-in equity of aces vs a random hand in holdem, we would write the following PQL query:
select avg(riverEquity(hero)) as heroEquity from game='holdem', hero='AA', villain='**'
OK, but the example above could have been achieved with the existing ProPokerTools Simulator! Got anything better?
Let's suppose we want to know how often a hand with two aces in omaha which starts as a favorite on the
flop gets outdrawn on the turn by a random hand, but then goes on to win the river.
We can answer that with the following query:
select count(HvHequity(villain, turn) > 0.5 and winsHi(hero)) as suckAndResuck
from game='omahahi', hero='AA**', villain='****'
where HvHequity(hero, flop) > 0.5
Not bad. What else ya got?
The following query will tell you how often A2 gets quartered (or sixthed) in omaha-8 against two decent
hands when it makes the nut low by the river:
select count(tiesLo(hero)) as lostSomeChips
from game='omaha8', hero='A2**', villain1='15%', villain2='15%'
where nutLo(hero, river) and not (winsHi(hero) or tiesHi(hero))
Hey, this is kind of fun!
I'm glad you think so! Here's another one.
This will show you what hand types (pair, two pair, etc.) win in stud in a 5-handed random race:
from game='studhi', syntax='generic', p1='*', p2='*', p3='*', p4='*', p5='*'
What games does PQL support?
'holdem', 'omahahi', 'omaha8', 'studhi', 'stud8', 'razz',
'omahahi5' (5-card omaha hi), 'omaha85' (5-card omaha-8)
Why did you call it PQL?
The syntax of PQL is loosely based on SQL (Structured Query Language) which is the industry standard
for querying databases. PQL uses a subset of the SQL operators and syntax
- AND, OR, NOT, ||, <> (not equal), =, >, >=, <, <=, SELECT, FROM, WHERE, AS, *, /, -, +,
CASE/WHEN/THEN/ELSE/END, IN, line comments (starting with -- and ending with a newline),
block comments (start with /* and end with */), and parentheses for grouping.
Who is the target audience for PQL?
PQL is intended for people with a decent level of technical and/or poker sophistication who nevertheless
do not have the time or inclination to write custom programs or mathematical proofs.
It is also intended for people who enjoy the process of exploring poker probability for its own sake.
SelectorsPQL supports the following selectors:
A PQL query supports any number of selectors separated by commas, and selectors can be given names using an optional 'as' clause. For example:
- avg - The 'avg' selector computes averages of numbers. For example 'avg(riverEquity(p1))'.
- count - The 'count' selector counts how often a given boolean expression evaluates to true. For example 'count(wins(p1))', 'count(handType(p1, river) = pair)', 'count(HvHequity(p1, flop) > 0.5 and HvHequity(p2, flop) > 0.3)'
- histogram - The 'histogram' selector takes an expression that returns one of equity, hand types, player counts, equity fractions, card counts, or strings, and shows how often each possible outcome occurs. For example 'histogram(riverEquity())', 'histogram(handtype(p2, river))', 'histogram(handshaving(minhandtype, flop, pair))', 'histogram(outsToHandType(p1, flop, straight))'
- max - The 'max' selector computes the maximum value of an expression. For example, 'max(handType(hero, flop))'
- min - The 'min' selector computes the minimum value of an expression. For example, 'min(fractionalRiverEquity(villain))'
select count(wins(hero)) as heroWon,
avg(riverEquity(hero)) as heroEV,
histogram(handtype(hero, fifth)) as fifthStreetHandType
From ClauseThe PQL from clause allows for the specification of the game (required), the board (if any),
the dead cards (if any), the syntax (if needed), and the range of hands for each player.
Syntax defaults to 'generic' if not specified.
Here is an example showing all of the options in a from clause:
from game='holdem', syntax='generic', board='KsJhTd', dead='2c',
hero='AsAd', looseyGoosey='**', tightOne='AA-TT, AK, AQ'
The PQL where clause is an optional boolean expression that must hold true before any selectors are evaluated.
It can be used to specify the situation more tightly than is possible with the from clause alone. For example:
where HvHequity(villain, flop) > HvHequity(hero, flop)
AND handtype(hero, turn) >= pair
FunctionsTodo - the pql function registry needs to be listed here.
handsHavingPQL has a special higher-order function called 'handsHaving'. Given a boolean function that takes a player
as its first argument, and values for all of the other arguments, it returns the number of players for which
the function evaluated to true. A couple of examples should give you the idea:
- handsHaving(minHandtype, river, flush) would evaluate to the number of players with a flush or better on the river.
- handsHaving(minHvREquity, flop, 0.3) would evaluate to the number of players with at least 30% Hand vs. Range equity on the flop.
- handsHaving(tiesHi) would evaluate to the number of players who tied for the hi half of the pot.
TypesPQL types are relatively simple and you probably don't need to know much about them, but for completeness, here they are.
- TBoardRange - a range of hands for the board, eg 'AxKxJy'
- TBoolean - true or false
- TCard - a single card, such as the Jack of Diamonds
- TCardCount - an integer between 0 and 52
- TDouble - a double precision floating point number, such as 0.123
- TEquity - a TDouble between 0.0 and 1.0
- TFlopHandCategory - what was made on the flop. This provides more specific information than THandType.
- TFraction - 1/2, 2/5, 13/914...
- THandType - a 5-card poker hand. Values in order:
- THiRating - a hi-hand rating - only useful when comparing to other THiRating
- TInteger, TLong - a whole number, such as 2, 3, 5, 7 or 11.
- TLoRating - a lo-hand rating - only useful when comparing to other TLoRating. In games where there is a qualifier, "no low" will have a TLoRating lower than every other TLoRating.
- TNumeric - base type for all numbers
- TPlayer - one of the players specified in the from clause, such as player1 or hero
- TPlayerCount - an integer between 0 and the number of players specified
- TRange - a range of hands, such as 'AA-TT'
- TRank - a Rank (an ace, a ten, a deuce, etc.)
- TRankSet - a Set of unique Ranks
- TStreet - for flop games, one of preflop, flop, turn, or river. For stud games, one of third, fourth, fifth, sixth, or seventh
- TString - a string in quotes, such as 'hello'