IPFLang Reference
A working syntax reference for IPFLang 1.4, with a runnable example for every construct. For the precise grammar instead of worked examples, see the formal grammar. To try any of this against live data, open Jurisdictions or Fees from the Explore menu above.
Overview
Inputs, fees, and verification
Writing a fee schedule in IPFLang means declaring what the inputs are and how each fee accrues from small, conditional amounts. There are six input types:
- String list with a single choice (
LIST) - String list with multiple choices (
MULTILIST) - Number, floating point, with lower and upper bounds and a default (
NUMBER) - Yes/no (
BOOLEAN) - Date, with temporal properties like years-to-now (
DATE) - Currency-typed monetary value (
AMOUNT)
Inputs become the HTML form the user fills in; their values drive the COMPUTE FEE
blocks. A schedule can also declare VERIFY COMPLETE or VERIFY MONOTONIC
directives, checked statically when the schedule is saved — see
Verification Directives below. Every calculation returns the full
list of steps taken to reach the result, applied or not, so the answer is auditable rather than
asserted.
Version Declaration
Optional, at most one, and must be the first thing in the file if present. Records when a schedule took effect and why it changed.
VERSION '2024.1' EFFECTIVE 2024-01-15 DESCRIPTION 'Annual fee increase' REFERENCE 'Federal Register Vol. 89, No. 123'
DESCRIPTION and REFERENCE are both optional, but recommended for auditability.
Single-Selection Input
Displays a list of choices and lets the user pick one. A default choice is required; a group is optional.
DEFINE LIST EntityType AS 'Select the desired entity type'
GROUP G1 (optional)
CHOICE NormalEntity AS 'Normal'
CHOICE SmallEntity AS 'Small'
CHOICE MicroEntity AS 'Micro'
DEFAULT NormalEntity
ENDDEFINE
Multiple-Selection Input
Displays a list of choices and lets the user pick any number of them. One or more default choices are required (comma-separated); a group is optional.
DEFINE MULTILIST EntityType AS 'Select the desired entity type'
GROUP G2 (optional)
CHOICE NormalEntity AS 'Normal'
CHOICE SmallEntity AS 'Small'
CHOICE MicroEntity AS 'Micro'
DEFAULT SmallEntity,NormalEntity
ENDDEFINE
To count selected choices, use the !COUNT property, e.g. EntityType!COUNT.
To test what was selected, use IN and NIN, e.g. YIELD 100 IF MicroEntity IN EntityType or YIELD 200 IF SmallEntity NIN EntityType.
Number Input
A floating-point value bounded by lower and upper limits. A default is required; a group is optional.
DEFINE NUMBER SheetCount AS 'Enter the number of sheets'
GROUP G3 (optional)
BETWEEN 10 AND 1000
DEFAULT 15
ENDDEFINE
Boolean Input
A yes/no selection. The default can be specified; a group is optional.
DEFINE BOOLEAN ContainsDependentClaims AS 'Does this contain dependent claims?'
GROUP G4 (optional)
DEFAULT TRUE
ENDDEFINE
Date Input
A date bounded by lower and upper limits, in DD.MM.YYYY format. A default is required; a group is optional. The special value TODAY resolves at runtime.
DEFINE DATE ApplicationDate AS 'Application date'
GROUP G5 (optional)
BETWEEN 01.01.2023 AND TODAY
DEFAULT 01.03.2023
ENDDEFINE
A date can't be used directly in arithmetic, but it exposes properties that can:
!YEARSTONOW— years from the date to today (a floating-point number).!MONTHSTONOW— months from the date to today.!MONTHSTONOW_FROMLASTDAY— months from the last day of the date's month to today. For 01.01.2023, that's counted from 31.01.2023.!DAYSTONOW— days from the date to today.
Amount Input
A monetary value in a fixed currency — for costs that vary by filing rather than by rule, such as a translation or search fee the user supplies. A default and a currency are required; a group is optional.
DEFINE AMOUNT TranslationCost AS 'Translation cost'
CURRENCY USD
DEFAULT 2000
GROUP G6 (optional)
ENDDEFINE
Like any currency-typed value, an AMOUNT can only be added to values in the same currency — see Currency Literals.
Input Grouping
Groups get their own display text and weight. On screen, inputs are grouped and ordered by weight — the heavier the group, the lower it appears.
Groups are usually declared in an autorun module that executes even when nothing else references it.
DEFINE GROUP G1 AS 'Application date inputs' WITH WEIGHT 100
DEFINE GROUP G2 AS 'Translation related inputs' WITH WEIGHT 150
DEFINE GROUP G3 AS 'Claim related inputs' WITH WEIGHT 200
Fee Definition
Any number of fees can be defined; all of them count toward the grand total. In its simplest form, a fee yields a single unconditional value.
COMPUTE FEE SimplestFee
YIELD 150
ENDCOMPUTE
Optional Fees
A fee can be marked OPTIONAL. It still counts toward the grand total, but is reported separately so the user can see what they could avoid.
COMPUTE FEE SimplestOptionalFee OPTIONAL
YIELD 150
ENDCOMPUTE
Conditional Fees
Add a condition to any YIELD. Here, BasicNationalFee depends on the EntityType selection.
Comparison operators: EQ, NEQ, LT, LTE, GT, GTE.
COMPUTE FEE BasicNationalFee
YIELD 320 IF EntityType EQ NormalEntity
YIELD 128 IF EntityType EQ SmallEntity
YIELD 64 IF EntityType EQ MicroEntity
ENDCOMPUTE
Conditional Fees (CASE blocks)
For logic that branches on one input and then varies by another, use CASE. YIELD statements outside any CASE are still evaluated normally.
COMPUTE FEE ExaminationFee
CASE SituationType EQ PreparedIPEA AS
YIELD 20 IF EntityType EQ NormalEntity
YIELD 40 IF EntityType EQ SmallEntity
YIELD 60 IF EntityType EQ MicroEntity
ENDCASE
YIELD 800 IF EntityType EQ NormalEntity
YIELD 360 IF EntityType EQ SmallEntity
YIELD 160 IF EntityType EQ MicroEntity
ENDCOMPUTE
Grouping related rules under CASE also makes completeness verification more useful — IPFLang can confirm each branch is itself complete.
Complex Amounts & Rounding
A YIELDed amount can be an arbitrary formula. Rounding uses FLOOR, ROUND, or CEIL.
FLOOR strips the decimal part (4.7 → 4). ROUND rounds to the
nearest integer (4.7 → 5, 4.3 → 4). CEIL rounds up (4.3 → 5).
COMPUTE FEE SheetFee
YIELD ROUND(420*((SheetCount-100)/50)) IF SheetCount GT 100 AND EntityType EQ NormalEntity
YIELD FLOOR(168*((SheetCount-100)/50)) IF SheetCount GT 100 AND EntityType EQ SmallEntity
YIELD CEIL(84*((SheetCount-100)/50)) IF SheetCount GT 100 AND EntityType EQ MicroEntity
ENDCOMPUTE
Currency Literals & Conversion
A number annotated with an ISO 4217 code becomes a typed monetary value. Same-currency arithmetic is valid; mixed-currency arithmetic is a compile-time error.
YIELD 100<EUR> + 50<EUR> ' valid: 150 EUR
YIELD 100<EUR> * 2 ' valid: 200 EUR, scalar multiplication
YIELD 100<EUR> + 50<USD> ' type error: EUR + USD
To combine currencies on purpose, convert explicitly — the conversion stays visible in the script rather than happening silently:
YIELD CONVERT(TranslationCost, USD, EUR) + PriorArtSearchFee
Polymorphic Fees
A fee can be generic over a currency using a type parameter, so the same logic works whichever currency it's invoked with.
COMPUTE FEE ScaledFee<C> RETURN C
YIELD 100<C> * Multiplier
ENDCOMPUTE
Choice Selection Test
Use IN and NIN to test MULTILIST selections.
COMPUTE FEE SheetFee
YIELD 100 IF Country1 IN Countries
YIELD 200 IF Country2 IN Countries
YIELD 25 IF Country1 NIN Countries AND Country2 NIN Countries
ENDCOMPUTE
Date Selection Test
Dates aren't compared directly; use their temporal properties instead.
DEFINE DATE D1 AS 'My birthday'
BETWEEN 01.01.1975 AND 31.12.1990
DEFAULT 31.10.1975
ENDDEFINE
COMPUTE FEE Fee1
YIELD 10 * ROUND(D1!YEARSTONOW) IF D1!YEARSTONOW GT 40
ENDCOMPUTE
Fee Local Variables
LET names an intermediate value inside a fee, to avoid repeating an expression and to keep the rule trace readable.
COMPUTE FEE SheetFee
LET A AS 20
LET B AS 40
YIELD A*200+B
ENDCOMPUTE
Returns
RETURN statements name what the engine reports back to the caller — typically totals.
RETURN ClaimLimits AS '10 claims included; additional fee as of 11'
RETURN ExReqDate AS 'Examination request due within 7 years after filing'
Verification Directives
Static checks, run when the schedule is saved — not at calculation time. A schedule that fails either is refused, with the specific gap named.
VERIFY COMPLETE confirms every possible input combination has a matching YIELD — no silently uncovered case:
VERIFY COMPLETE FEE BasicNationalFee
VERIFY MONOTONIC confirms a fee moves the right way as a named numeric input grows — e.g. more claims should never produce a smaller bill:
VERIFY MONOTONIC FEE ClaimFee WITH RESPECT TO ClaimCount DIRECTION NonDecreasing
DIRECTION is optional (default NonDecreasing) and also accepts
NonIncreasing, StrictlyIncreasing, and StrictlyDecreasing.
Complete Example
Use this as a starting point for your own fee schedule.
DEFINE LIST EntityType AS 'Select the desired entity type'
CHOICE NormalEntity AS 'Normal'
CHOICE SmallEntity AS 'Small'
CHOICE MicroEntity AS 'Micro'
DEFAULT NormalEntity
ENDDEFINE
DEFINE LIST SituationType AS 'Situation type'
CHOICE PreparedIPEA AS 'IRRP (Chapter II) prepared by the IPEA/US'
CHOICE PaidAsISA AS 'International search fee paid as ISA'
CHOICE PreparedISA AS 'Search report prepared by an ISA other than the US'
CHOICE AllOtherSituations AS 'All other situations'
DEFAULT PreparedIPEA
ENDDEFINE
DEFINE NUMBER SheetCount AS 'Enter the number of sheets'
BETWEEN 10 AND 1000
DEFAULT 15
ENDDEFINE
DEFINE NUMBER ClaimCount AS 'Number of claims'
BETWEEN 0 AND 1000
DEFAULT 0
ENDDEFINE
DEFINE BOOLEAN ContainsDependentClaims AS 'Does this contain dependent claims?'
DEFAULT TRUE
ENDDEFINE
COMPUTE FEE BasicNationalFee
YIELD 320 IF EntityType EQ NormalEntity
YIELD 128 IF EntityType EQ SmallEntity
YIELD 64 IF EntityType EQ MicroEntity
ENDCOMPUTE
VERIFY COMPLETE FEE BasicNationalFee
COMPUTE FEE SearchFee
CASE SituationType EQ PreparedIPEA AS
YIELD 0 IF EntityType EQ NormalEntity
YIELD 0 IF EntityType EQ SmallEntity
YIELD 0 IF EntityType EQ MicroEntity
ENDCASE
CASE SituationType EQ PaidAsISA AS
YIELD 140 IF EntityType EQ NormalEntity
YIELD 56 IF EntityType EQ SmallEntity
YIELD 28 IF EntityType EQ MicroEntity
ENDCASE
CASE SituationType EQ PreparedISA AS
YIELD 540 IF EntityType EQ NormalEntity
YIELD 216 IF EntityType EQ SmallEntity
YIELD 108 IF EntityType EQ MicroEntity
ENDCASE
YIELD 700 IF EntityType EQ NormalEntity
YIELD 280 IF EntityType EQ SmallEntity
YIELD 140 IF EntityType EQ MicroEntity
ENDCOMPUTE
COMPUTE FEE ExaminationFee
CASE SituationType EQ PreparedIPEA AS
YIELD 0 IF EntityType EQ NormalEntity
YIELD 0 IF EntityType EQ SmallEntity
YIELD 0 IF EntityType EQ MicroEntity
ENDCASE
YIELD 800 IF EntityType EQ NormalEntity
YIELD 360 IF EntityType EQ SmallEntity
YIELD 160 IF EntityType EQ MicroEntity
ENDCOMPUTE
COMPUTE FEE SheetFee
LET A AS 420
LET B AS 420
LET C AS 420
YIELD ROUND(A*((SheetCount-100)/50)) IF SheetCount GT 100 AND EntityType EQ NormalEntity
YIELD ROUND(B*((SheetCount-100)/50)) IF SheetCount GT 100 AND EntityType EQ SmallEntity
YIELD ROUND(C*((SheetCount-100)/50)) IF SheetCount GT 100 AND EntityType EQ MicroEntity
ENDCOMPUTE
COMPUTE FEE ClaimFee
YIELD (480*ClaimCount) IF ClaimCount GT 3 AND EntityType EQ NormalEntity
YIELD (192*ClaimCount) IF ClaimCount GT 3 AND EntityType EQ SmallEntity
YIELD (96*ClaimCount) IF ClaimCount GT 3 AND EntityType EQ MicroEntity
ENDCOMPUTE
VERIFY MONOTONIC FEE ClaimFee WITH RESPECT TO ClaimCount
This covers everyday schedule-writing. Jurisdiction composition (one .ipf file inheriting
inputs and fees from another) and the temporal helpers behind renewal and grace-period logic are
documented in the IPFLang repository,
along with the formal type system for anyone who wants the full typing rules.