-
Notifications
You must be signed in to change notification settings - Fork 9
Language Reference
Alex Ozdemir edited this page Jan 11, 2021
·
1 revision
LFSC is a dependently-typed LISP variant. It's type-checked is used as a proof-checker for SMT by way of (a) the Curry-Howard correspondence and (b) a set of declarations for SMT terms, sorts, and inference rules.
We explain the base syntax of the language here. There are three classes of syntactic forms: terms, side-condition terms, and commands.
-
Non-Negative Integer Literals: written in the standard way; e.g.,
5
. -
Non-Negative Rational Literals:
N/M
for valid integer literalsN
andM
- Type of integers:
mpq
- Type of rationals:
mpz
- Type of types:
type
- Hole:
_
: an unspecified term, whose value must be inferable during type-checking. Creates a type-checking error if not inferable.
-
Let-binding:
(@ VAR VAL BODY)
: a term equal toBODY
withVAR
(locally) set toVAL
.-
let
is an alias for@
.
-
-
Dependent Type:
(! VAR TYPE BODY)
: a function from terms to types.- When applied to
VAL
of typeTYPE
, has typeBODY
, withVAR
set toVAL
. - In the case that
VAR
is free inBODY
, this is a non-dependent function type. -
Forall
is an alias for!
- When applied to
-
Ascription:
(: TYPE VAL)
: a term equal toVAL
which is enforce to have typeTYPE
. -
Un-ascribed Function:
(\ VAR BODY)
: a function whose argument has an un-annotated type- Only valid in a context where that type can be inferred
-
lam
is an alias for\
-
Ascribed function:
(# VAR TYPE BODY)
: an ascribed function-
VAR
must have typeBODY
-
-
Side condition:
(^ SC-TERM SC-TERM2|VAR)
: a side-condition on type-checking- Only valid as an argument type for a
!
term - Causes code to run during type-checking
- If the second argument is a fresh identifier, evaluates the side-condition
term
SC-TERM
, and binds the value toVAR
- Otherwise, evaluates both side-condition terms, and asserts equality
-
provided
is an alias for^
- Only valid as an argument type for a
-
Arrow:
(-> DECLS RESULT)
: alias for nested!
-terms-
DECLS
is a declaration list, surrounded by parentheses, in which each item is- a named declaration:
(: VAR TYPE)
: sayingVAR is a TYPE
. - an anonymous declaration:
TYPE
: saying that some unnamed variable is aTYPE
.
- a named declaration:
- the
DECLS
list can be understood as binding a bunch of (named or anonymous) variables to new symbols of the indicated types - Creates a nested
!
-term:(! VAR1 TYPE1 (! VAR2 TYPE2 ... RESULT))
-
The following forms are used to build numeric (integer or rational) terms. While integers and rationals are distinct types (without a sub-typing relationship), the following forms can be used to create terms of either type, unless otherwise notes.
-
Sum:
(mp_add NUM NUM)
-
Product:
(mp_mul NUM NUM)
-
Division:
(mp_div NUM NUM)
-
Negation:
(mp_neg NUM)
or(~ NUM)
-
Integer-to-Rational Conversion:
(mpz_to_mpq NUM)
-
Zero Branching:
(mp_ifzero NUM T F)
- Evaluates
NUM
. If zero, evaluatesT
, elseF
- Evaluates
-
Negative Branching:
(mp_ifneg NUM T F)
- Evaluates
NUM
. If negative, evaluatesT
, elseF
- Evaluates
-
Pattern Matching
(match DISC ((PAT0 CASE0) (PAT1 CASE1) ... ))
- Evaluate
DISC
, then find a matching pattern, then evaluate the correspondingCASEi
- Patterns have the following forms
-
default
: matches any -
SYM
: matches a declared symbol (by name) -
(SYM VAR0 VAR1 ... )
: matches an application of the declared symbolSYM
, to arguments, which are bound as theVARi
-
- Patterns are checked in-order
- Evaluate
-
Compare:
(compare A B T F)
- evaluates
A
andB
, compares them under an arbitrary, but total term order, and then evaluatesT
ifA < B
, otherwiseF
.
- evaluates
-
If Equal:
(ifequal A B T F)
- evaluates
A
andB
, checks them for pointer equality, and evaluatesT
if they're equal, andF
otherwise. - somewhat undefined for non-declared symbols
- evaluates
-
Fail:
fail
: if evaluated, causes type-checking to fail
All defined & declared symbols in LFSC have a set of marks (bits) associated with them. Some SC terms, when evaluated, manipulate those marks.
-
(ifmarkedN C T F
): branch on mark- If
N
is missing, it is treated as1
- Evaluates
C
; if theN
th mark is set, evaluatesT
, otherwiseF
- If
-
(markvarN C
): branch on mark- If
N
is missing, it is treated as1
- Evaluates
C
; then toggles theN
th mark on it
- If
-
(do A B)
: evaluateA
, thenB
; keepB
's value- The evaluation of
A
may change marks
- The evaluation of
-
Declaration:
(declare VAR TYPE)
: setsVAR
to be a fresh symbol with typeTYPE
-
Definition:
(define VAR TERM)
: setsVAR
to beTERM
, with a corresponding type -
Opaque Definition:
(define VAR TERM)
: setsVAR
to be a fresh symbol, with the type ofTERM
's type. -
Declare Rule:
(declare-rule VAR DECLS TYPE)
: equivalent to(declare VAR (-> DECLS TYPE))
-
Declare Type:
(declare-type VAR DECLS)
: equivalent to(declare VAR (-> DECLS type))
-
Define Const:
(define-const VAR DECLS TERM)
:- creates a nested annotate function with the arguments from
DECLS
and the bodyTERM
. The function is bound toVAR
- see the
->
term for documentation aboutDECLS
- creates a nested annotate function with the arguments from
-
Check:
(check TERM)
: check thatTERM
is well-typed -
Check with Assumptions:
(check DECLS TYPE TERM)
:- Under bindings induced by decls, check that
TERM
has typeTYPE
- see the
->
term for documentation aboutDECLS
- Under bindings induced by decls, check that
-
Program Definition:
(program ARGS TYPE BODY)
:- Declare/define a SC function which takes
ARGS
, returns typeTYPE
, withBODY
. -
ARGS
is a parentheses-surrounded list of members of form(VAR TYPE)
- Declare/define a SC function which takes
-
Run:
(run SC-TERM)
: evaluatesSC-TERM