l3 - github pages

39
L3 Contents 1 Language Features 1 1.1 Commenting ............... 1 1.2 Primitive Types .............. 1 1.3 Literals .................. 2 1.4 Global State ................ 3 1.5 Tuples .................. 3 1.6 Maps ................... 4 1.7 Sum Types ................ 4 1.8 Records .................. 5 1.9 Registers ................. 5 1.10 Polymorphic Types ............. 6 1.11 Statements and Expressions ......... 6 1.12 Defining Constants and Operations ...... 10 1.13 Components ............... 11 1.14 Recursion ................. 12 1.15 Instruction Set Definitions .......... 14 2 Tutorial 16 A Primitive Types and Operations 21 A.1 Unit ................... 21 A.2 Bool ................... 21 A.3 Nat ................... 22 A.4 Int .................... 22 A.5 Bit-vectors ................ 23 A.6 Bit-strings ................ 25 A.7 Characters and Strings ........... 26 A.8 Floating-point ............... 27 A.9 Miscellaneous operations .......... 28 B Syntax 34 1 Language Features is document gives a overview of the L3 specification language. e language is imperative, first-order, case-sensitive and strongly typed. 1.1 Commenting Block comments are delimited by ‘{-’ and ‘-}’. Inline comments start with ‘--’ and extend to the end of the current line. All commented code is simply ignored. Block comments can be nested, which means that it is possible to comment out code that already contains comments. 1.2 Primitive Types e primitive types of the language are: unit bool char nat int bits(·) rounding . Types can be combined into tuples (with the ‘*’ operator) and maps (with the ‘->’ operator). Finite set, option and list types can be formed with the ‘set’, ‘option’ and ‘list’ postfixes. An equality type is any type that excludes map types. e equality comparison operation ‘==’ can only be used to compare members of equality types. Furthermore, sets can only be constructed over equality types. e infix ‘::’ is used for type annotation. For example, ‘1::bits(16)’ denotes a 16-bit word with value one. For convenience, this bit-vector annotation can be shortened to ‘1`16’. 1

Upload: others

Post on 03-Dec-2021

5 views

Category:

Documents


0 download

TRANSCRIPT

L3

Contents1 Language Features 1

11 Commenting 112 Primitive Types 113 Literals 214 Global State 315 Tuples 316 Maps 417 Sum Types 418 Records 519 Registers 5110 Polymorphic Types 6111 Statements and Expressions 6112 Defining Constants and Operations 10113 Components 11114 Recursion 12

115 Instruction Set Definitions 14

2 Tutorial 16

A Primitive Types and Operations 21A1 Unit 21A2 Bool 21A3 Nat 22A4 Int 22A5 Bit-vectors 23A6 Bit-strings 25A7 Characters and Strings 26A8 Floating-point 27A9 Miscellaneous operations 28

B Syntax 34

1 Language FeaturesThis document gives a overview of the L3 specification language The language is imperativefirst-order case-sensitive and strongly typed

11 CommentingBlock comments are delimited by lsquo-rsquo and lsquo-rsquo Inline comments start with lsquo--rsquo and extend to theend of the current line All commented code is simply ignored Block comments can be nestedwhich means that it is possible to comment out code that already contains comments

12 Primitive TypesThe primitive types of the language are

unit bool char nat int bits(middot) rounding Types can be combined into tuples (with the lsquorsquo operator) and maps (with the lsquo-gtrsquo operator)Finite set option and list types can be formed with the lsquosetrsquo lsquooptionrsquo and lsquolistrsquo postfixes Anequality type is any type that excludes map types The equality comparison operation lsquo==rsquo canonly be used to compare members of equality types Furthermore sets can only be constructedover equality types

The infix lsquorsquo is used for type annotation For example lsquo1bits(16)rsquo denotes a 16-bit wordwith value one For convenience this bit-vector annotation can be shortened to lsquo1`16rsquo

1

Synonyms The lsquotypersquo construct can be used to introduce new type synonyms for example thefollowing are valid type declarations

type word = bits(32)type mem = bits(32) -gt bits(8)type foo = word set mem bool

Type synonyms can be used interchangeably with their defining type In the context of the typedeclarations above we can introduce a new constant lsquofourrsquo as follows

word four = 4bits(32)

The extra type annotation is unnecessary here but it helps demonstrate that lsquobits(32)rsquo and thesynonym lsquowordrsquo are effectively one and the same

13 LiteralsThe lsquounitrsquo type has a single element lsquo()rsquo The lsquoboolrsquo type has two elements lsquotruersquo and lsquofalsersquo Thestring type lsquostringrsquo is a pseudonym for lsquochar listrsquo String literals are represented using doublequotes and character literals are preceded by a hash for example lsquohellorsquo is a string and lsquoarsquo isa character The type lsquoroundingrsquo has four elements lsquoroundTiesToEvenrsquo lsquoroundTowardPositiversquolsquoroundTowardNegativersquo and lsquoroundTowardZerorsquo

The language supports three numeric types lsquonatrsquo lsquointrsquo and lsquobits(middot)rsquo Number literals canbe expressed using binary decimal or hexadecimal notation as indicated by the prefixes lsquo0brsquo lsquo0drsquoand lsquo0xrsquo respectively1 An additional prefix character (lsquonrsquo lsquoirsquo or lsquowrsquo) can be used to avoid explicittype annotation for example lsquo0i15rsquo and lsquo0ixFrsquo both denote the integer value fifteen A numberwithout any prefixes is treated as a decimal bit-vector wherein leading zeroes are ignored Bit-vectors can be represented using a special quotation syntax for example lsquo0101rsquo is equivalentto lsquo0b101`4rsquo

Bit-string literals L3 allows lists of Booleans (bit-strings) to be treated as numeric valueswith the head of the list representing the most significant bit No constraint is placed on thelength of bit-strings2 This makes bit-strings distinct from bit-vectors which are fixed width(as constrained by the type) The prefix character lsquosrsquo may be used to identify bit-string literalsLeading zeroes are significant when bit-string values are presented in binary or hexadecimalformats for example the expressions lsquo0b00001101bool listrsquo and lsquo0sx0Drsquo both represent thelist

list false false false false true true false true

Consequently the bit-string values lsquo0sxDrsquo and lsquo0sx0Drsquo are not equal Note that leading zeroes areignored in decimal bit-string expressions for example lsquo029bool listrsquo lsquo0sd29rsquo and lsquo0s11101rsquoall represent the same bit-string When the prefix lsquosrsquo is used on its own the expression is parsedas a binary value (this means that lsquo0s20rsquo will fail to parse)

1Octal is not supported2The bit-string type represents a countably infinite set of values

2

14 Global StateGlobal variables are introduced using the lsquodeclarersquo construct which adds elements to the globalstate-space The following represent valid variable declarations

declare number natdeclare integer int boolean bool -- two declarationsdeclare pc bits(32) r1 bits(64) -- commas are optional

At the point of declaration it is not possible to specify initial values Users can specify (and latercall) their own initialisation procedures if required

The lsquolt-rsquo operator is used to assign values to mutable variables for example

pc lt- 0xF -- an assigment

assigns value lsquo0xFrsquo to our declared global variable lsquopcrsquo The bit-string and bit-vector types alsopermit assignment to bit-ranges for example

pclt30gt lt- 0xF pclt31gt lt- true -- a sequence of assigments

will set the bottom four bits and then the most-significant bit of lsquopcrsquo

15 TuplesTuples can be formed using the pairing constructor lsquorsquo which associates to the right Bracketingis optional (but recommended) for example all of the following expressions are semanticallyidentical

one true falseone (true false)(one true false) -- preferred form(one (true false))

These expressions have type lsquostring bool boolrsquo3 Note that the expression

((one true) false)

has type lsquo(string bool) boolrsquo which makes it strictly type distinct from (incompatiblewith) the previous expression

Note that (in expressions) commas are the loosest binding operator which means that

x y == 3 4

will parse as

(x ((y == 3) 4)) -- fully elaborated form

and not as

(x y) == (3 4) -- this could be what was intended

It is advisable that users only drop brackets when there is little chance of ambiguity3This is the same as lsquostring (bool bool)rsquo

3

16 MapsMaps are used to represent total functions4 For example the declaration

type map nat -gt int -- a map type pseudonym

introduces a type pseudonym for maps with domain lsquonatrsquo and codomain lsquointrsquo Maps and singlemap entries can be assigned to for example given the declaration

declare -- three global maps

m1 mapm2 mapm3 nat -gt nat

the statement m1 lt- m2 m1(1) lt- 2

will set map lsquom1rsquo to be lsquom2rsquo and this map is then updated so that lsquom1(1)rsquo takes value lsquo2rsquoThe language encourages the use of simple un-curried maps which means that the type

type map bool nat -gt int

should be used in preference totype nmap nat -gt inttype map bool -gt nmap

In particular the language does not permit the syntax lsquom(true)(2)rsquo whereas lsquom(true 2)rsquo is fineThe language does not provide a mechanism for specifying anonymous functions or anonymous

maps5 Furthermore maps and operations (either primitive or user defined) are considered to bedistinct As such it is not possible to make assignments of the form lsquom3 lt- Log2rsquo

17 Sum TypesEnumerated and sum (tagged union) types can be introduced using the lsquoconstructrsquo keywordFor example the declaration

construct enumerated Zero One Two Three -- a new type called enumerated

introduces a new type lsquoenumeratedrsquo that consists of four elements (new constants) Sum typescan be declared in a similar manner for example

construct bool_option BoolNone BoolSome bool -- an unnecessary variant of bool option

The elements of this new type are lsquoBoolNonersquo lsquoBoolSome(false)rsquo and lsquoBoolSome(true)rsquo6 Everyconstructor of the sum type must map from a pre-existing type (or be nullary) and this precludesthe definition of new recursive or mutually recursive datatypes

Enumerated types (where every constructor is nullary) admit casting tofrom numeric types7For example lsquo[One]natrsquo is equal to lsquo0n1rsquo and lsquo[0n1]enumeratedrsquo is equal to lsquoOnersquo

4Maps must have an equality type as their domain They can be viewed as a form of array and are typically usedto model memories and register banks

5The function lsquofn x =gt x + 1rsquo is an example of an anonymous function in Standard ML6The brackets are needed here for example lsquoBoolSome truersquo will not parse7The same does not hold for general sum types

4

18 RecordsRecord types can be introduced using the lsquorecordrsquo construct The following is an example of arecord declaration

record rec

number natinteger intboolean bool

Every value of type lsquorecrsquo has three components which may be accessed using dot notation forexample if we have a global variable

declare rec rec

then the sub-elements are lsquorecnumberrsquo lsquorecintegerrsquo and lsquorecbooleanrsquo The language does notprovide a syntax for record literals As such records must be built up incrementally for examplethe following is a sequence of assignments to components of the variable lsquorecrsquo

recnumber lt- 1 recinteger lt- 2 recboolean lt- true

It is not possible to express this with a single assignment to lsquorecrsquo

19 RegistersRegister types can be introduced using the lsquoregisterrsquo construct for example

register sreg bits(32)

31-28 FLAGS7-0 27-16 MODE15-12 MASK

This declares a new type lsquosregrsquo that represents the following 32-bit register31 28 27 16 15 12 11 8 7 0

FLAGS MODElt110gt MASK MODElt1912gt

Note that the bit-field 118 of lsquosregrsquo does not correspond with a named component Also notethat fields are allowed to be non-contiguous which is the case for the lsquoMODErsquo field Register typesare essentially special forms of record types with the automatic specification of bijections toa bit-vector representation Each named bit-field can be accessed using the dot notation forexample if we have

declare status sreg

then the fields lsquostatusFLAGSrsquo and lsquostatusMASKrsquo have type lsquobits(4)rsquo and lsquostatusMODErsquo has typelsquobits(20)rsquo Unlike records register types automatic admit casting tofrom an underlying bit-vector type The expression lsquoampstatusrsquo gives the value of the register (with type lsquobits(32)rsquo) andlsquosreg(0xFFFF0000)rsquo constructs a register of type lsquosregrsquo It is possible to use this notation to updatearbitrary bit-fields of a register for example the statement

ampstatuslt207gt lt- 11101101100111

will update the bit-field 207 of lsquostatusrsquo using the 14-bit literal value

5

110 Polymorphic TypesUsers cannot declare their own polymorphic types Furthermore all user defined operations andvariables must be monomorphic The language does however provide support for three built-inpolymorphic datatypes which may be used under the proviso that these types are always fullytype instantiated (free of type variables)

1101 ListsThe language provides limited support for working with lists Lists can be specified as follows

list 0n0 2 4 -- a list of naturals (length three)0n0 2 3 Nil -- expanded versionCons (0n0 Cons (2 Cons (4 Nil))) -- equivalent version

These expressions have type lsquonat listrsquo Given the first-order nature of L3 only simple listoperations are provided (for example lsquoHeadrsquo lsquoTailrsquo and lsquoLengthrsquo) Higher-order list operationssuch as filter map and fold are not available

1102 Finite SetsThe language provides basic support for finite sets Sets can be specified as follows

set 0n0 2 4 -- a three element set (of naturals)0n0 insert 2 insert 4 insert set -- an expanded versionSetOfList (list 0n0 2 4 ) -- a version built from a list

These expressions have type lsquonat setrsquo The infix operators lsquoinrsquo and lsquonotinrsquo test for set member-ship for example the expressions

0n0 in set 0 2 4 -- test for membership0n1 notin set 0 2 4 -- test for non-membership

both evaluate to lsquotruersquo Sets can only be defined over equality types It is not possible forexample to construct the type lsquo(bool -gt bool) setrsquo

1103 Option TypesThe option type is a polymorphic sum type that has two constructors lsquoNoneα optionrsquo andlsquoSomeαrarrα optionrsquo Option types are helpful when specifying partial operations

111 Statements and ExpressionsThis section presents the statements and expressions of the language Statements can be groupedinto blocks using the syntax

statement1 -- do thisstatement2 -- then do thismiddot middot middot

6

Each block and sub-statement has type lsquounitrsquo The operator lsquorsquo is strictly binary trailing semi-colons not permitted at the end of a sequence of statements Expressions are distinct fromstatements in particular expressions preclude assignments

1111 NothingThe statement lsquonothingrsquo has no effect Its primary purpose is to facilitate the specification ofcontrol flows wherein some paths do something (update the state) and others do nothing8

1112 ConditionalsThe language supports if-then-else statements and expressions and when-do statements Thelatter is provided as a convenient shorthand that is to say the statement

when p do x

is equivalent to the statement

if p then x else nothing

Note that the language does not support layout syntax (the off-side-rule)

1113 For LoopsThe language provides support for simple for-loop statements On each iteration of a for-loopa natural number index variable is either incremented or decremented (by one) This process isrepeated until the index value reaches a pre-computed upper or lower bound for example theloop statements

for i in 1 3 do proc(i)for i in 3 1 do proc(i)

are respectively equivalent to

proc(1) proc(2) proc(3) proc(3) proc(2) proc(1)

The initial and final loop index values may be arbitrary natural number expressions As suchit may be the case that the loop direction will only be known once these bound expressions arecomputed

In addition to regular for loops the language also supports foreach loops which operate overlists For example the following code makes three calls to lsquoprocrsquo

foreach i in list 0n2 4 6 do proc(i)

Note that this construct will also work for bit-strings and for normal stringsThere is no support for do while or repeat until loops

8The lsquonothingrsquo statement is essentially syntactic sugar for lsquo()rsquo

7

1114 Exceptions Unknown and UndefinedThe keyword lsquoUNKNOWNrsquo is used to represent an unspecified element which may be of any giventype The language does not stipulate whether or not this value should be chosen deterministi-cally If the value were chosen deterministically then the expression lsquoUNKNOWN == UNKNOWNrsquo willalways be lsquotruersquo However if the choice is non-deterministic then there is no way of knowing ifan occurrence of this expression is lsquotruersquo or lsquofalsersquo

The language supports user defined exceptions which may be raised but not caught Thelsquoexceptionrsquo keyword is used to declare new exception categories for example

exception ASSERT string

introduces a new exception lsquoASSERTrsquo that takes a single string as an argument This exception canbe raised in expressions and statements as follows

ASSERT (an error has occurred)

Thus exceptions can be used to flag the occurrence of a variety of different errors The L3interpreter will stop when an exception is raised Exceptions can be raised within expressionsand are not constrained by return type

The behaviour of various operations is undefined on some inputs for example the arithmeticexpression lsquox div 0n0rsquo is undefined For any given undefined expression the language permitsthree possible interpretations (implementations)

bull A deterministic value can be chosen For example lsquox div 0n0rsquo is equal to lsquo0n0rsquo is a validinterpretation of this undefined expression

bull A non-deterministic value can be chosen In particular is not necessary for the expressionlsquox div 0n0 == x div 0n0rsquo to be lsquotruersquo

bull An exception can be raised

It is expected that specifications will be designed with some preferred treatment of undefinedbehaviour in mind In this example one possible way to manage undefined cases is by takingcare to explicitly write code of the form lsquoif n == 0 then else x div n rsquo This willensure that undefined cases are unreachable

1115 Procedure CallsA procedure is any user defined operation with return type lsquounitrsquo Procedures typically providefunctionality by means of updating the global state (through side effects) Procedures can becalled (and exceptions can be raised) in statement blocks for example

middot middot middotproc (1 true) -- this is a procedure callmiddot middot middot

The following code is valid but not recommended

8

middot middot middotASSERT error -- raise an exceptionproc (1 true) -- the L3 interpreter will never reach this code

In the above the exception is unconditionally raised so the remaining code should be regardedas unreachable (redundant)

1116 Local VariablesThe L3 language supports two varieties of variables mutable and immutable All global vari-ables are mutable The keyword lsquovarrsquo is used to declare new mutable variables with local scopeLocal variables can be introduced anywhere within a statement block and these variables canbe assigned to using the lsquolt-rsquo operator Immutable variables are introduced within a block usingthe syntax lsquox = expr rsquo and this is treated as a let-statement An immutable value cannot beupdated however it can fall out of scope by declaring a new immutable variable with the samename The operators lsquolt-rsquo and lsquo=rsquo are not permitted in expressions

The specification below uses two mutable variables lsquoxrsquo and lsquoyrsquo

var y = zvar x = yif p then xlt30gt lt- 1111 y lt- x + 1

else xlt74gt lt- 1111 y lt- 0 return (x + y)

This could be respecified using immutable variables for example

y = zx = yx y = if p then (x || 00001111 x || 00001111 + 1)

else (x || 11110000 0)return (x + y)

It is not always easy to eliminate mutable variables In this case the second specification ismore cumbersome because the bit-field update has been replace by an explicit mask (bitwise-or)operation This operations has been repeated in specify the value of lsquoyrsquo because assignments arenot permitted in expressions

Mutable variables can be declared without an initial assignment for example lsquovar xrsquo isequivalent to lsquovar x = UNKNOWNrsquo

1117 PatternMatchingThe language supports match statements and expressions Pattern matching is supported withrespect to literals (see Section 13) constructors9 (immutable) variables wildcards (anonymousvariables) and bit-patterns

9This includes matching on tuples as well as lsquoNonersquo lsquoSomersquo lsquoConsrsquo and lsquoNilrsquo Matching on finite sets and recordfields is not possible

9

Given the type declarations

construct enum One Two Three construct data

NoDataData1 string bits(8)Data2 enum bits(16)

the following illustrates a match expression

match y

case -1 NoData or -2 NoData =gt 0`4 -- note use of orcase _ Data1 (hello 11 x 11) =gt x + 1 -- use of bit-patterncase i Data2 (Three 1111 y) =gt [i] + ylt30gtcase 1 Data2 (_ 8) =gt 4case _ =gt 8

The body (right-hand side of lsquo=gtrsquo) of the first case line with a matching pattern is selected Thesymbol lsquo_rsquo is a wildcard and will match any value The lsquoorrsquo construct provides a shorthand forwriting blocks of clauses with differing patterns but the same body

The terms lsquo11 x 11rsquo and lsquo1111 yrsquo are called bit-patterns and they will match against a setof bit-vector values From the type declaration of lsquodatarsquo it is known that the variable lsquoxrsquo mustrepresent a 4-bit value because it occurs in the middle of an 8-bit word (the match requires bitslsquo11rsquo as a prefix and as a suffix) Likewise lsquoyrsquo must be a 12-bit value Multiple variables can occurin a bit-patterns for example lsquo1 x 1 y 0rsquo is a valid bit-pattern The type checker will oftenbe able to infer the type of pattern variables and if this fails type annotations can be added

The lsquopatternrsquo construct can help avoid situations where explicit annotations are repeatedlyrequired (causing clutter in patterns) If for example the variable lsquoimm5rsquo is frequently used tomatch a 5-bit value then the following declaration can be made

pattern imm5 bits(5)

In subsequent code the default type for pattern variable lsquoimm5rsquo will be lsquobits(5)rsquo The lsquopatternrsquoconstruct only influences type checking If a particular type hint is no longer appropriate thenit can be dropped for example one can insert the declaration lsquoclear pattern imm5rsquo

112 Defining Constants and OperationsUsers can construct operational semantics style formal specifications in L3 by defining their ownconstants and operations There is no module system or facility for local definitions all userdefinitions are made at the top-level with global scope User constants and operations cannot beoverloaded or redefined

A pure constant is a nullary (zero argument) operation that is state independent for examplethe following code declares a new constant

bits(32) UINT_MAX = 0xFFFFFFFF

10

The following code declares operations that are nullary but state dependent

declare number Natnat numberPlus1 = return (number + 1)unit incNumber = number lt- numberPlus1

Users can also declare new unary operations which may or may not be state dependent forexample

nat numberMinusN (nnat) = return (number + n) -- state dependentunit decNumber () = number lt- numberMinusN (1)nat mla (mnatnnatanat) = return (m n + a) -- pure

The operation lsquomlarsquo is unary because it takes a single triple as an argument To enhance clarityand avoid misunderstandards users may elect to specify nullary state dependent operations usinga single lsquounitrsquo argument Given the declarations above the expression lsquodecNumber()rsquo gives theclear impression that a call is being made (with possible side-effects) wheres the expressionlsquoincNumberrsquo does not

At the point of declaration operation arguments must be fully type annotated and onlymonomorphic types are allowed10 It is nevertheless possible to declare bit-vector operationsthat are valid with respect to some given set of bit widths for example the following are validdeclarations

--- valid for any bit-vector width N ---bits(N) bv_mla (mbits(N) nbits(N) abits(N)) = return (m n + a)

--- valid for sufficiently wide bit-vectors (N greater than eight) ---bool bit8 (xbits(N)) with N gt 8 = return (xlt8gt)

An L3 type error will arise if ever an application of the operation lsquobit8rsquo violates the bit widthconstraint Note that vector width variables (such as lsquoNnatrsquo above) can be used as if they werea regular variables in the definitional body of an operation

113 ComponentsWhen specifying instruction set architectures the two most significant programmerrsquos modelcomponents are typically the main memory and a collection of general purpose registers In theMIPS architecture for example there are thirty-two general purpose registers which may berepresented using the following map

declare gpr bits(5) -gt bits(64)

The statement

gpr(d) lt- gpr(r)10An compile time error will arise if the type checker is not able to infer all types the final definition must be

free of type variables

11

then expresses moving a value from register lsquorrsquo to register lsquodrsquo However register a memory accessis frequently more complicated than this in particular registers can be banked and memory canbe complex11 As such it is often necessary to specify collections of operations for accessing(reading and writing) these components With the MIPS example register zero is special (it isa constant value) and so one could define the following operations

bits(64) read_gpr (nbits(5)) = if n == 0 then 0 else gpr (n)unit write_gpr (vbits(64) nbits(5)) = when n ltgt 0 do gpr (n) lt- v

Thus the previous register transfers would now be specified as follows

write_gpr (read_gpr (n) d)

This precise style of specification is not entirely satisfying though since it departs in appearancefrom the pseudo code found in MIPS reference manuals The L3 language provides a specialmechanism for specifying a pair of operations that read and write state components With theMIPS example the following declaration can be made

component GPR (nbits(5)) bits(64)

value = if n == 0 then 0 else gpr(n)assign value = when n ltgt 0 do gpr(n) lt- value

One can then write

GPR(d) lt- GPR(r)

which is closer to the syntax used in the MIPS reference manuals The lsquocomponentrsquo constructeffectively provides a controlled form of operator overloading whereby the lsquoassignrsquo operation12

is select when the operator name appears on the left-hand side of an assignment (lsquolt-rsquo) and thelsquovaluersquo operation13 is applied otherwise Semantically these two operations are exactly the sameas the manually defined versions lsquowrite_gprrsquo and lsquoread_gprrsquo The ldquowriterdquo operation will alwayshave a lsquounitrsquo return type Users are free to specify the ldquoreadrdquo and ldquowriterdquo operations in any mannerthat they deem appropriate however the ldquowriterdquo operation cannot be defined recursively norcan the ldquoreadrdquo operation call the ldquowriterdquo operation

114 RecursionThe language permits the definition of recursive operations It is not possible to define mutuallyrecursive operations

The L3 language has been designed to act as an authoring front-end for the HOL4 theoremprover facilitating the task of writing instruction set specifications In order to successfullyimport an L3 specification it is necessary for the HOL4 system to prove that every user defined

11ARM registers are banked according to processor mode Memory can often be accessed with big- and little-endian byte ordering Special treatment may be needed for unaligned memory addresses for example when readinga 16-bit value from an odd address There may also be address translation (virtualisation) and memory hierarchies(caching)

12In this example the ldquowriterdquo operations is internally called lsquowriteGPRrsquo13Internally the ldquoreadrdquo operation is simply called lsquoGPRrsquo

12

operation is total (terminates on all inputs) If an L3 function is non-terminating then it willbe impossible to export that definition to HOL4 If a function is terminating but the standardautomation of HOL4 is unable to construct a termination proof then it may be necessary toprovide the prover with a hint in the form of a measure

Consider the following specification

declare m bits(8) -gt bits(8)

unit load (abits(8) lbits(8) list) =match l

case Nil =gt nothingcase Cons (h t) =gt m(a) lt- h load (a + 1 t)

The lsquoloadrsquo operation recurses over the list lsquolrsquo loading values into the map lsquomrsquo At the time ofwriting this documentation trying to build the exported HOL4 version of this specificationgives rise to the following error message

Initial goal

existRWF R andforallstate a l h t

(l = ht) rArrR ((a + 1wt)state with m = (a =+ h) statem) ((al)state)

Exception raised at TotalDefnDefinebetween beginning of frag 0 and end of frag 0at TotalDefndefnDefine

Unable to prove termination

Try using TotalDefntDefine ltnamegt ltquotationgt lttacgt

This occurs because HOL4 is unable to automatically prove that lsquoloadrsquo always terminates Toget around this problem the original L3 specification can be modified to contain an annotationas follows

unit load (abits(8) lbits(8) list) measure Length(l) =

The metadata lsquomeasure Length(l)rsquo tells HOL4 to examine the length of the list lsquolrsquo since thisvalue will decrease upon each recursive call to lsquoloadrsquo When the length of the list is zero (thelsquoNilrsquo case) there are no recursive calls so termination is guaranteed

The expression occurring after the lsquomeasurersquo keyword must be of type lsquonatrsquo After provid-ing a measure it is still possible that HOL4 will fail to prove termination either because thesupplied measure is incorrect or because the termination proof is non-trivial (requires humanguidance andor custom lemmas) If this occurs then users should either simplifyrewrite theirspecifications or if necessary report the problem

13

115 Instruction Set DefinitionsWhen working with instruction set models it is helpful to construct a datatype that representsthe set of machine (low-level) instructions This datatype constitutes a simple form of abstractsyntax tree (AST) and it can be used to build instruction decoders (identifying machine-codeinstructions and splitting opcodes into sub-fields) instruction encoders (generating opcodes fora given instruction) next-state functions (applying a semantics function for a given instruction)and assembly code parsers

By way of an example consider the MIPS instruction ANDI this instruction has the assemblycode syntax

ANDI rt rs immediate

and the following 32-bit machine-code encoding

31 26 25 21 20 16 15 0

001100 rs rt immediate6 5 5 16

The semantics of this instruction can be expressed with the operation

unit run_ANDI (rsbits(5) rtbits(5) immbits(16)) =GPR(rt) lt- GPR(rs) ampamp ZeroExtend (imm)

One could use this operation to directly specify a next-state function which would be of theform

unit Next =match Fetch -- fetches a 32-bit opcode from memory

middot middot middotcase 001100 rs rt imm =gt run_ANDI (rs rt imm)middot middot middot

This style of specification is direct and concise however it does lack some of the flexibility thatcomes with using an instruction datatype The L3 language provides support for an slightlydifferent style of specification This alternative approach is explained by first examining howone would specify things manually (explicitly) and then showing how L3 can streamline thisprocess

Firstly one could explicitly define an AST datatype for MIPS instructions it would be ofthe form

construct instruction

middot middot middotANDI bits(5) bits(5) bits(16)middot middot middot

14

This datatype provides a suitable constructor for the ANDI instruction It is now possible to definea decoder which maps opcodes onto AST entries for example

instruction Decode (opcbits(32)) =match opc

middot middot middotcase 001100 rs rt imm =gt ANDI (rs rt imm)middot middot middot

This decoder can be used to define our next-state function that is

unit Next = Run (Decode (Fetch))

where lsquoRunrsquo is defined by

unit Run (iinstruction) =match i

middot middot middotcase ANDI (args) =gt run_ANDI (args)middot middot middot

When working with full-scale architecture specifications (where the AST type is large) thereare some clear overheads associated with implementing this approach (in comparison with theAST free version) It becomes challenging to maintain the AST datatype declaration and tokeep it correctly synchronised with the instruction semantics operations (such as lsquorun_ANDIrsquo)and the definition of lsquoRunrsquo Note however that there is great uniformity in the AST datatypedeclaration and also in the definition of lsquoRunrsquo As such L3 is able to automatically define bothof these for the user

To make use of this automation the declaration of lsquorun_ANDIrsquo is simply modified to

define ANDI (rsbits(5) rtbits(5) immbits(16)) =GPR(rt) lt- GPR(rs) ampamp ZeroExtend (imm)

The lsquodefinersquo keyword tells L3 to define a semantics function14 (as before) and to also create anew lsquoinstructionrsquo datatype AST entry furthermore the two will be linked with the automaticconstruction of a lsquoRunrsquo function The lsquoinstructionrsquo type and lsquoRunrsquo function become defined (inscope) following the declaration lsquodefine Runrsquo After this declaration it is no longer possible touse the lsquodefinersquo construct again however it does become possible to define functions such aslsquoDecodersquo and lsquoNextrsquo

Specifications that are based on using lsquodefinersquo gain the benefits of declaring an instructionAST datatype without the downside of laborious coding overheads In the example above theoverhead amounts to one extra line of code this comes from defining a next-state function thatcalls the dedicated decode function followed by a call to lsquoRunrsquo

One of the key advantages of declaring an instruction datatype is that it makes it consider-ably easier to develop tools that work with assembly code syntax (performing parsing encoding

14This function is internally called lsquodfnANDIrsquo instead of lsquorun_ANDIrsquo

15

and pretty-printing) In this case it is relatively easy for example to map between the MIPSinstruction syntax andi $5 $6 1024 and the expression lsquoANDI (5 6 1024)rsquo Defining anencoder in L3 is relatively straightforward for example

bits(32) Encode (iinstruction) =match i

middot middot middotcase ANDI (rs rt imm) =gt 001100 rs rt immmiddot middot middot

Such a function can be used to write a MIPS assembler which would map the assembly codesyntax andi $5 $6 1024 onto the machine-code value 0x30c50400

2 TutorialThis section gives a brief overview of how to install and use L3

Installation The sources for L3 can be downloaded from the following webpage

wwwclcamacuk~acjf3l3

The file l3tarbz2 can be unpacked with the command

$ tar xvjf l3tarbz2

This will create a directory of the form L3-YYYY-MM-DD where the year month and day willcorrespond with the release date The current version of L3 depends upon PolyML 57 whichcan be obtained from the site polymlorg If PolyML is installed then L3 can be built as follows

$ cd L3-YYYY-MM-DD$ make

Once built the following should appear when you start L315

$ l3ltlt L3 gtgtgt

Users should consider running L3 with the command rlwrap l316

15This assumes that the directory L3-YYYY-MM-DDbin has been added to the PATH environment variable16Details on rlwrap utility can be found at the site freecodecomprojectsrlwrap

16

Basic Interaction The command prompt for L3 is essentially the read-eval-print loop (REPL)of PolyML As such users are free to write arbitrary Standard ML code The structure Runtimeenables interaction with L3 The following shows an arithmetic evaluation in Standard ML aswell as in the L3 interpreter (evalQ)

gt 1 + 2val it = 3 intgt RuntimeevalQ `0i1 + 2`val it = `0i3` Termterm

Various error messages can occur when using the interpreter for example

gt RuntimeevalQ `1 + 2`Exception- Fail Could not infer all types raised

gt RuntimeevalQ `0i2 div 0`Exception- Except (Div SOME (div (int [`0i2` `0i0`]))) raised

The first error occurs because unannotated number literals are regarded as bit-vector values andhere the vector width cannot be inferred

L3 declarations can be made using the function loadQ The following sequence shows thedeclaration and manipulation of a global variable

gt RuntimeloadQ `declare n nat`ltVARgt nval it = () unit

gt RuntimeevalQ `n`val it = `UNKNOWNnat` Termterm

gt RuntimeevalQ ` n lt- 3 n `val it = `0n3` Termterm

The global state can be examined using the function show for example

gt Runtimeshow()val it = [(n `0n3`)] Evalterm_stack

The state can be ldquowipedrdquo clean using the function reset and all declarations can be wiped usinglsquoresetAllrsquo for example

gt Runtimereset()val it = () unitgt Runtimeshow()val it = [(n `UNKNOWNnat`)] Evalterm_stack

gt RuntimeresetAll()val it = () unitgt Runtimeshow()val it = [] Evalterm_stack

The function lsquoLoadQrsquo is similar to lsquoloadQrsquo but it performs a lsquoresetAllrsquo before making declarations

17

Constants The structure Consts provides various functions for working with L3 constantsMany of the operation in the Consts structure will be of little interest to end-users however itcan be used to display some helpful information

The function ConstslookupConst can be used to lookup an operation for example

gt ConstslookupConst Log2val it = Primitive [(bits(a) -gt bits(a) -) (nat -gt nat -)] const

Since lsquoLog2rsquo is a primitive operation only the valid types (ordered by overload priority) are showWith user operations the internal representation (definition) of the operation will be shownfor example

gt RuntimeLoadQ `unit demo () = ()`gt ConstslookupConst demoval it = Definition (Abs ([(_ (unit -))] unit -gt unit `()`) NONE 1)

Constsconst

The functions ConstslistDefinitions and ConstslistExceptions provide details of all useroperations and exceptions respectively The function lsquoConstsstatsrsquo gives a summary of all thecurrent declarations

gt Constsstats()Primitives 188Destructors 5Constructors 0Accessors 0Exceptions 0User operations 1Instruction definitions 0

Here the constructors for primitive types (such as lsquoConsrsquo) are counted under ldquoprimitivesrdquo

Types The Types structure can be used to display information relating to L3 types In partic-ular this structure provides the functions TypeslookupConst and TypeslistConsts which aredemonstrated below

gt RuntimeloadQ `construct enum One Two Three`gt TypeslistConsts()val it =

[(enumeq = true ast = false def = Constructors (Enum ltdict(3)gt) num = 0)]

(string typeconst) list

gt TypeslookupConst intval it = SOME eq = true ast = false def = BaseType num = ~1

typeconst option

18

Loading and Exporting Specifications When writing an L3 specification it is expected thatuser declarations will be contained in an L3 source file A sample instruction set specification(tinyspec) can be found in the L3 distribution subdirectory examples This specification isbased on Thackerrsquos pedagogical Tiny 3 architecture it can be loaded as follows

gt RuntimeLoadF tinyspecLoading tinyspecltTYPgt regTltTYPgt wordTmiddot middot middotltFUNgt test_progDone

The string argument to the functions RuntimeloadF and RuntimeLoadF can be in the form ofa comma separated list of files which will be loaded in order That is the call

RuntimeloadF aspec bspec

will load aspec followed by bspecThe function HolExportexport will export the current L3 specification in the form of an

HOL4 script for example

gt HolExportexport tinyraiseexception okfunction okmiddot middot middotmextend skipmunextend skipCreated file tinyScriptsmlCreated file tinyLibsmlCreated file tinyLibsigDone

The function HolExportspec provides a convenient shortcut for performing LoadF and exportusing just a single call for example HolExportspec (tinyspec tiny) will perform theload and export presented above

L3 is capable of exporting two styles of HOL specification an explicitly monadic version(based on state_transformerTheory) and a version that directly manipulates state using let-expressions (which is the default style) For example a monadic version of the Tiny specifi-cation can be exported using the command HolExportspec (tinyspec tiny monadic)Other export options include sigdocs nosigdocs (for setting HOLrsquos TheoryPPinclude_docstrace variable) bigrecords nobigrecords (for controlling HOLrsquos Datatypebig_record_size)and underflowbefore nounderflowbefore (for selecting the required IEEE 754 underflow be-haviour)

Generated HOL4 specifications are not designed to be manually edited (or human readable)To build an L3 specification script the HOL library Import is needed This library is currentlylocated in the directory $HOL_DIRexamplesl3-machine-codecommon and so adding this path tothe INCLUDES variable of a local Holmakefile is recommended The examplesl3-machine-codedirectory contains various examples of using L3 generated specifications

19

Testing Specifications Having written an L3 specification it is fairly easy to write code (inStandard ML) that runs test vectors Code for running the tinyspec example can be found inthe file run-tinyspec In this test harness the Tiny state is initialised and a small test programis loaded simply by evaluating the expression lsquoinitialize (test_prog)rsquo

It is also possible to evaluate (run) models that have been exported to HOL4 The filerun-tinysml shows how this can be accomplished for the Tiny example

20

A Primitive Types and OperationsThe primitive types are as follows

unit bool char nat int bits(middot) rounding

There are two infix type constructors lsquorsquo for pairs and lsquo-gtrsquo for maps There are also postfix typeconstructors lsquosetrsquo lsquooptionrsquo and lsquolistrsquo for example sets of strings are represented by the typelsquostring setrsquo The following sections describe these primitive types together with some detailsof associated operations The following constants and operations are available

nullary () Nil None false roundTiesToEven roundTowardNegativeroundTowardPositive roundTowardZero true

prefix - ~ Abs Cardinality Cons Difference Drop Element FP32_AbsFP32_Add FP32_Equal FP32_IsNan FP32_LessThan FP32_MulFP32_Neg FP32_Sub FP64_Abs FP64_Add FP64_Equal FP64_IsNanFP64_LessThan FP64_Mul FP64_Neg FP64_Sub FromBinStringFromDecString FromHexString Fst Head IndexOf InitMapIntersection IsAlpha IsAlphaNum IsDigit IsHexDigit IsLowerIsMember IsSome IsSubset IsUpper Length Log2 Max Min MsbQuotRem Remove RemoveDuplicates RemoveExcept ReverseSetOfList SignExtend SignedMax SignedMin Size Snd Some TailTake ToLower ToUpper Union Update ValOf ZeroExtend not

infix = ampamp + - lt lt+ lt= lt=+ ltgt == gt gt+ gt= gt=+ ^ || gtgtltlt gtgt+ ltlt gtgt and div in insert mod notin or quot rem

sdivsmodother middot ltmiddotgt middot ltmiddotmiddotgt [middot] fields splitl splitr tokens

Many arithmetic operations are overloaded Unless otherwise stated the order of selection islsquobits(middot)rsquo lsquonatrsquo lsquointrsquo and then lsquobool listrsquo

A1 UnitThe type lsquounitrsquo represents the singleton set containing the value lsquo()rsquo The primary use of thistype is as the return type for procedures

A2 BoolThe type lsquoboolrsquo represents the two element set B = lsquotruersquo lsquofalsersquo The following standardBoolean operations are available

negation not bool rarr boolconjunction and booltimes bool rarr booldisjunction or booltimes bool rarr boolequality == αtimesα rarr boolnon-equality ltgt = αtimesα rarr bool

21

The infix operators lsquoandrsquo and lsquoorrsquo are interpreted with short-circuit evaluation for example in theexpression lsquofalse and f()rsquo the value of lsquof()rsquo is not computed as the overall expression will alwaysevaluate to false This short-circuiting influences the side-effects that occur during expressionevaluation

There are two prefix symbols for logical negation (these are semantically identical) with lsquorsquobinding slightly tighter than lsquonotrsquo This distinction is becomes significant when working withequalities for example lsquonot a == brsquo is taken to be not(a = b) whereas lsquoa == brsquo is (nota) = b

Equality is only defined with respect to equality types represented here by the type variableα An equality type is any type built without the used of the map operator lsquo-gtrsquo

A3 NatThe type lsquonatrsquo represents the natural numbers N = 0 1 2 The following operations areavailable

logarithm (base two) Log2 nat rarr natminimum value Min nattimes nat rarr natmaximium value Max nattimes nat rarr natless than lt nattimes nat rarr boolgreater than gt nattimes nat rarr boolless than or equal to lt= nattimes nat rarr boolgreater than or equal to gt= nattimes nat rarr booladdition + nattimes nat rarr natsubtraction - nattimes nat rarr natmultiplication nattimes nat rarr natexponentiation nattimes nat rarr natdivision div nattimes nat rarr natmodulus mod nattimes nat rarr nat

The lsquodivrsquo and lsquomodrsquo operations satisfy the following property

foralln 0 lt n =rArr forallk k = (k div n) lowast n+ (k mod n) and (k mod n) lt n

The expressions lsquoLog2(0)rsquo lsquox div 0rsquo and lsquox mod 0rsquo are all undefined 17

A4 IntThe type lsquointrsquo represents the integers Z = Ncupminus1minus2minus3 The following operations areavailable

17The interpreter will raise an exception when attempting to evaluate them

22

unary minus - int rarr intabsolute value Abs int rarr intminimum value Min inttimes int rarr intmaximum value Max inttimes int rarr intless than lt inttimes int rarr boolgreater than gt inttimes int rarr boolless than or equal to lt= inttimes int rarr boolgreater than or equal to gt= inttimes int rarr booladdition + inttimes int rarr intsubtraction - inttimes int rarr intmultiplication inttimes int rarr intexponentiation inttimes nat rarr intquotient and remainder QuotRem inttimes int rarr inttimes intquotient quot inttimes int rarr intremainder rem inttimes int rarr intdivision div inttimes int rarr intmodulus mod inttimes int rarr int

The operation lsquoAbsrsquo gives an positive integer value for example lsquoAbs(-2)rsquo = lsquo2rsquo The integeroperations lsquoquotrsquo and lsquodivrsquo are related to natural number division as follows

i quot j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

and

i div j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(minusi) div n(j))minus 1 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i and n(i) mod n(minusj) = 0

minus z(n(i) div n(minusj))minus 1 j lt 0 and 0 le i and n(i) mod n(minusj) = 0

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

where z NrarrZ and n ZrarrN are value preserving maps The lsquoremrsquo and lsquomodrsquo operations satisfythe equations

i rem j =

iminus (i quot j) lowast j j = 0

undefined j = 0i mod j =

iminus (i div j) lowast j j = 0

undefined j = 0

A5 Bit-vectorsThe type lsquobits(n)rsquo represents fixed-width (n-bit) words also known as bit-vectors for examplebits(32) is the type of 32-bit machine words18 The bits type can be viewed as representing

18These are called double-words (dword) in the x86 architecture and simply words in the ARM architecture

23

the set Zn = 0 1 2nminus1 for some 0 lt n At the type system level no distinction is madebetween signed and unsigned words however some operations (such as orderings) have signedand unsigned variants

The following bit-vector operations are available

1rsquos complement ~ bits(n) rarr bits(n)2rsquos complement - bits(n) rarr bits(n)absolute value Abs bits(n) rarr bits(n)logarithm (base two) Log2 bits(n) rarr bits(n)zero-extend ZeroExtend bits(m) rarr bits(n)sign-extend SignExtend bits(m) rarr bits(n)reverse bits Reverse bits(n) rarr bits(n)minimum value (u) Min bits(n)times bits(n) rarr bits(n)maximum value (u) Max bits(n)times bits(n) rarr bits(n)minimum value (s) SignedMin bits(n)times bits(n) rarr bits(n)maximum value (s) SignedMax bits(n)times bits(n) rarr bits(n)widthsize Size bits(n) rarr natmost-significant (sign) bit Msb bits(n) rarr boolbit value middot ltmiddotgt bits(n)times nat rarr boolbit field middot ltmiddotmiddotgt bits(m)times nattimes nat rarr bits(n)concatenation bits(m)times bits(n) rarr bits(p)duplication ^ bits(m)times nat rarr bits(n)less than (s) lt bits(n)times bits(n) rarr boolgreater than (s) gt bits(n)times bits(n) rarr boolless than or equal to (s) lt= bits(n)times bits(n) rarr boolgreater than or equal to (s) gt= bits(n)times bits(n) rarr boolless than (u) lt+ bits(n)times bits(n) rarr boolgreater than (u) gt+ bits(n)times bits(n) rarr boolless than or equal to (u) lt=+ bits(n)times bits(n) rarr boolgreater than or equal to (u) gt=+ bits(n)times bits(n) rarr booladdition + bits(n)times bits(n) rarr bits(n)subtraction - bits(n)times bits(n) rarr bits(n)multiplication bits(n)times bits(n) rarr bits(n)quotient (s) quot bits(n)times bits(n) rarr bits(n)remained (s) rem bits(n)times bits(n) rarr bits(n)division (u) div bits(n)times bits(n) rarr bits(n)modulus (u) mod bits(n)times bits(n) rarr bits(n)division (s) sdiv bits(n)times bits(n) rarr bits(n)modulus (s) smod bits(n)times bits(n) rarr bits(n)bitwise conjunction ampamp bits(n)times bits(n) rarr bits(n)bitwise disjunction || bits(n)times bits(n) rarr bits(n)bitwise exclusive-or bits(n)times bits(n) rarr bits(n)

Unsigned operations are labelled with (u) and signed operations are labelled with (s)The shift operations support shifting by either a bit-vector value or by a natural number value

The overloading is resolved such that the lsquonatrsquo variant is selected over the lsquobits(middot)rsquo version Theshift operations are

24

left-shift ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (u) gtgt+ bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (s) gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate left ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate right gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

A number of operations are undefined depending on the types of their domain and rangeThis is detailed in the following table

Operation Undefined when

ZeroExtend(x`n)`m m lt nSignExtend(x`n)`m m lt n(x`m)ltpgt m le p(x`m)lthlgt`n n = h+ 1minus l or h lt l orm le h((xm) (yn))`p p = m+ n((x`m) ^ n)`p p = m middot n (which covers n = 0)

The type checker will fail when these conditions are obviously violated Alternatively the inter-preter may raise a runtime error when these conditions are not met

As before the expressions lsquoLog2(0)rsquo lsquox quot 0rsquo lsquox rem 0rsquo lsquox div 0rsquo and lsquox mod 0rsquo are allundefined

A6 Bit-stringsVarious bit-string operation are defined over the type lsquobool listrsquo These are listed below

bit value middot ltmiddotgt bool listtimes nat rarr boolbit field middot ltmiddotmiddotgt bool listtimes nattimes nat rarr bool listconcatenation bool listtimes bool list rarr bool listduplication ^ bool listtimes nat rarr bool listaddition + bool listtimes bool list rarr bool listbitwise conjunction ampamp bool listtimes bool list rarr bool listbitwise disjunction || bool listtimes bool list rarr bool listbitwise exclusive-or bool listtimes bool list rarr bool listleft-shift ltlt bool listtimes nat rarr bool listright-shift gtgt+ bool listtimes nat rarr bool listrotate-right gtgt bool listtimes nat rarr bool list

The bit value operation gives the truth value of a bit-string at a given bit position for example

lsquo0s1101lt0gtrsquo = lsquotruersquo lsquo0s1101lt1gtrsquo = lsquofalsersquo lsquo0s1101lt2gtrsquo = lsquotruersquolsquo0s1101lt3gtrsquo = lsquotruersquo lsquo0s1101lt4gtrsquo = lsquofalsersquo lsquo0s1101lt5gtrsquo = lsquofalsersquo

25

The least-significant bit (position zero) occurs to the right of the bit-string The bit value oper-ation gives lsquofalsersquo when the bit position is greater than the size of the bit-string

The bit field operation extracts a range of bits from a bit-string For example

lsquo0s1101lt31gtrsquo = lsquo0s110rsquo and lsquo0s1101lt52gtrsquo = lsquo0s0011rsquo

In the bit-string expression xlthlgt the size of the result is always h + 1 minus l and the result isundefined when h lt l

Bit-string addition does not require the arguments to be of the same size and it gives anon-truncated result For example

lsquo0s101 + 0s1rsquo = lsquo0s110rsquo and lsquo0s101 + 0s11rsquo = lsquo0s1000rsquo

The operation ltlt performs a left-shift for example lsquo0s1101 ltlt 2rsquo = lsquo0s110100rsquo The oper-ation lsquorsquo is bit-string concatenation and lsquo^rsquo is duplication for example

lsquo0s101 0s11rsquo = lsquo0s10111rsquo and lsquo0s101 ^ 3rsquo = lsquo0s101101101rsquo

Regular list operations work as one would expect over bit-strings for example lsquoHead (0s101)rsquois a valid expression with value lsquotruersquo

A7 Characters and StringsThe following built-in functions are available for characters and strings

is alphabetic IsAlpha char rarr boolis alpha-numeric IsAlphaNum char rarr boolis decimal digit IsDigit char rarr boolis hexadecimal digit IsHexDigit char rarr boolis lowercase IsLower char rarr boolis uppercase IsUpper char rarr boolparse binary FromBinString string rarr num optionparse decimal FromDecString string rarr num optionparse hexadecimal FromHexString string rarr num optionconvert to lowercase ToLower string rarr stringconvert to uppercase ToUpper string rarr string

The following string operations are useful for parsing

split from the left splitl (char rarr bool) times string rarr string times stringsplit from the right splitr (char rarr bool) times string rarr string times stringsplit into fields fields (char rarr bool) times string rarr string listsplit into tokens tokens (char rarr bool) times string rarr string list

These are based on the SML functions Substringsplitl Substringsplitr Stringfieldsand Stringtokens Character predicates are declared using special syntax for example theexpression

splitl space or hexdigit and not in set a f ( 12bcab)

gives the result lsquo( 12bc ab)rsquo

26

A8 Floating-pointThe L3 language does not provide specialised types for representing floating-point numbersHowever 32-bit (single precision) and 64-bit (double precision) bit-vector values can be treatedas floating-point numbers the following IEEE compliant encoding formats are assumed

31 30 23 22 0

s e m1 8 23

63 62 52 51 0

s e m1 11 52

Here lsquosrsquo is the sign bit (set to lsquo1rsquo for negative numbers) lsquoersquo is a biased exponent value and lsquomrsquo is thesignificand The following constants and operations are available (where lsquofprsquo stands for bits(32)or bits(64) depending on the name of the operation)

rounding modes roundTiesToEvenroundTowardPositiveroundTowardNegativeroundTowardZero

ieee_rounding

flags (record) DivideByZero InvalidOpOverflow PrecisionUnderflow

ieee_flagsrarrbool

comparison values FP_LT FP_EQ FP_GT FP_UN ieee_compare

convert format FP32_ToFP64 fp32rarrfp64convert format FP64_ToFP32 ieee_roundingtimes fp64rarrfp32convert format FP64_ToFP32_ ieee_roundingtimes fp64rarr

ieee_flagstimes fp32from integer FP32|64_FromInt ieee_roundingtimes intrarrfpto integer FP32|64_ToInt ieee_roundingtimes fprarrint optionfrom string FP32|64 stringrarrfp

negative zero FP32|64_NegZero fppositive zero FP32|64_PosZero fpnegative infinity FP32|64_NegInf fppositive infinity FP32|64_PosInf fpa quiet NaN FP32|64_qNan fpa signalling NaN FP32|64_sNan fp

is integral FP32|64_IsIntegral fprarrboolis finite FP32|64_IsFinite fprarrboolis NaN FP32|64_IsNan fprarrboolis signalling NaN FP32|64_IsSignallingNan fprarrboolis normal FP32|64_IsNormal fprarrboolis sub-normal FP32|64_IsSubnormal fprarrboolis zero FP32|64_IsZero fprarrbool

27

comparison FP32|64_Compare fptimes fprarrieee_compareequality FP32|64_Equal fptimes fprarrboolless than FP32|64_LessThan fptimes fprarrboolless than or equal FP32|64_LessEqual fptimes fprarrboolgreater than FP32|64_GreaterThan fptimes fprarrboolgreater than or equal FP32|64_GreaterEqual fptimes fprarrbool

absolute FP32|64_Abs fprarrfpnegation FP32|64_Neg fprarrfpsquare root FP32|64_Sqrt ieee_roundingtimes fprarrfp(with flags) FP32|64_Sqrt_ ieee_roundingtimes fprarrieee_flagstimes fpaddition FP32|64_Add ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Add_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpsubtraction FP32|64_Sub ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Sub_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpmultiplication FP32|64_Mul ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Mul_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpfused multiply-add FP32|64_MulAdd ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulAdd_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpfused multiply-sub FP32|64_MulSub ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulSub_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpdivision FP32|64_Div ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Div_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fp

The L3 interpreter supports evaluation for 32-bit and 64-bit floating-point expressions but onlywhen running on an x86 machine that supports SSE2 extensions (Pentium 4 and later) Thefused multiply-addsub operations can only be interpreted on machines supporting the FMAextension which came in with the 4th generation (Haswell) Intel processors These restrictionsalso apply to any Standard ML code that is generated by L3

The IEEE 754 standard permits a number of different ways to flag underflow L3 predomi-nantly supports the x86 interpretation which detects underflow after rounding However whenexporting to HOL4 it is possible to choose detection before rounding which for example issuited to ARM instruction set models

A9 Miscellaneous operationsThe following operations are available

pair constructor αtimes β rarr αtimes βfirst of pair Fst αtimes β rarr αsecond of pair Snd αtimes β rarr β

casting [middot] α rarr βinitialise a map InitMap α rarr (βrarrα)

28

option constructor Some αrarrα optionoption projection ValOf α option rarr αoption test IsSome α option rarr bool

set membership in αtimesα set rarr boolset non-membership notin αtimesα set rarr boolset insertion insert αtimesα set rarrα setset union Union α settimesα set rarrα setset intersection Intersect α settimesα set rarrα setset difference Difference α settimesα set rarrα setset subset test IsSubset α settimesα set rarr boolset cardinality Cardinality α setrarr natset from a list SetOfList α list rarrα set

empty list Nil α listlist constructor Cons αtimesα list rarr α listlist head Head α list rarr αlist tail Tail α list rarr α listlist length Length α list rarr natlist concatenation α listtimesα list rarr α listlist flatten Concat α list list rarr α listlist element Element nattimesα list rarr αlist prefix Take nattimesα list rarr α listlist drop prefix Drop nattimesα list rarr α listlist pad left PadLeft αtimes nattimesα list rarr α listlist pad right PadRight αtimes nattimesα list rarr α listlist update Update αtimes nattimesα list rarr α listlist difference Remove α listtimesα list rarr α listlist intersection RemoveExcept α listtimesα list rarr α listlist without duplicates RemoveDuplicates α listrarr α listlist membership IsMember αtimesα list rarr boollist member position IndexOf αtimesα list rarr nat option

Sets are only defined over equality types see Appendix A2 The casting map is defined overcast-able types (as represented by the polymorphic type variables α and β) these are the primitivetypes (with the exception of lsquounitrsquo) and user defined enumerated types Assume lsquoEnumrsquo and lsquoEnum2rsquoare declared with

construct Enum One Two Three construct Enum2 Four Five Six Seven

The cast operations are described in Tables 1 to 7

29

Table 1 Cast to lsquoboolrsquo

From Operation Examples

bool identity lsquo[true]boolrsquo = lsquotruersquostring parse bool lsquo[true]boolrsquo = lsquotruersquo

lsquo[false]boolrsquo = lsquofalsersquootherwise undefined

nat is not zero lsquo[0n3]boolrsquo = lsquotruersquolsquo[0n0]boolrsquo = lsquofalsersquo

int is not zero lsquo[-0i1]boolrsquo = lsquotruersquolsquo[0i0]boolrsquo = lsquofalsersquo

bool list is not zero lsquo[0s11]boolrsquo = lsquotruersquolsquo[0s0]boolrsquo = lsquofalsersquo

bits(middot) is not zero lsquo[3`3]boolrsquo = lsquotruersquolsquo[0`3]boolrsquo = lsquofalsersquo

Enum is not the first element lsquo[One]boolrsquo = lsquofalsersquolsquo[Two]boolrsquo = lsquotruersquo

Table 2 Cast to lsquostringrsquo

From Operation Examples

bool name lsquo[true]stringrsquo = lsquotruersquostring identity lsquo[hello]stringrsquo = lsquohellorsquonat decimal lsquo[0n3]stringrsquo = lsquo3rsquoint signed decimal lsquo[-0i1]stringrsquo = lsquo~1rsquobool list binary lsquo[0s11]stringrsquo = lsquo11rsquobits(middot) unsigned hexadecimal lsquo[139`8]stringrsquo = lsquo8BrsquoEnum name lsquo[One]stringrsquo = lsquoOnersquo

30

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

Synonyms The lsquotypersquo construct can be used to introduce new type synonyms for example thefollowing are valid type declarations

type word = bits(32)type mem = bits(32) -gt bits(8)type foo = word set mem bool

Type synonyms can be used interchangeably with their defining type In the context of the typedeclarations above we can introduce a new constant lsquofourrsquo as follows

word four = 4bits(32)

The extra type annotation is unnecessary here but it helps demonstrate that lsquobits(32)rsquo and thesynonym lsquowordrsquo are effectively one and the same

13 LiteralsThe lsquounitrsquo type has a single element lsquo()rsquo The lsquoboolrsquo type has two elements lsquotruersquo and lsquofalsersquo Thestring type lsquostringrsquo is a pseudonym for lsquochar listrsquo String literals are represented using doublequotes and character literals are preceded by a hash for example lsquohellorsquo is a string and lsquoarsquo isa character The type lsquoroundingrsquo has four elements lsquoroundTiesToEvenrsquo lsquoroundTowardPositiversquolsquoroundTowardNegativersquo and lsquoroundTowardZerorsquo

The language supports three numeric types lsquonatrsquo lsquointrsquo and lsquobits(middot)rsquo Number literals canbe expressed using binary decimal or hexadecimal notation as indicated by the prefixes lsquo0brsquo lsquo0drsquoand lsquo0xrsquo respectively1 An additional prefix character (lsquonrsquo lsquoirsquo or lsquowrsquo) can be used to avoid explicittype annotation for example lsquo0i15rsquo and lsquo0ixFrsquo both denote the integer value fifteen A numberwithout any prefixes is treated as a decimal bit-vector wherein leading zeroes are ignored Bit-vectors can be represented using a special quotation syntax for example lsquo0101rsquo is equivalentto lsquo0b101`4rsquo

Bit-string literals L3 allows lists of Booleans (bit-strings) to be treated as numeric valueswith the head of the list representing the most significant bit No constraint is placed on thelength of bit-strings2 This makes bit-strings distinct from bit-vectors which are fixed width(as constrained by the type) The prefix character lsquosrsquo may be used to identify bit-string literalsLeading zeroes are significant when bit-string values are presented in binary or hexadecimalformats for example the expressions lsquo0b00001101bool listrsquo and lsquo0sx0Drsquo both represent thelist

list false false false false true true false true

Consequently the bit-string values lsquo0sxDrsquo and lsquo0sx0Drsquo are not equal Note that leading zeroes areignored in decimal bit-string expressions for example lsquo029bool listrsquo lsquo0sd29rsquo and lsquo0s11101rsquoall represent the same bit-string When the prefix lsquosrsquo is used on its own the expression is parsedas a binary value (this means that lsquo0s20rsquo will fail to parse)

1Octal is not supported2The bit-string type represents a countably infinite set of values

2

14 Global StateGlobal variables are introduced using the lsquodeclarersquo construct which adds elements to the globalstate-space The following represent valid variable declarations

declare number natdeclare integer int boolean bool -- two declarationsdeclare pc bits(32) r1 bits(64) -- commas are optional

At the point of declaration it is not possible to specify initial values Users can specify (and latercall) their own initialisation procedures if required

The lsquolt-rsquo operator is used to assign values to mutable variables for example

pc lt- 0xF -- an assigment

assigns value lsquo0xFrsquo to our declared global variable lsquopcrsquo The bit-string and bit-vector types alsopermit assignment to bit-ranges for example

pclt30gt lt- 0xF pclt31gt lt- true -- a sequence of assigments

will set the bottom four bits and then the most-significant bit of lsquopcrsquo

15 TuplesTuples can be formed using the pairing constructor lsquorsquo which associates to the right Bracketingis optional (but recommended) for example all of the following expressions are semanticallyidentical

one true falseone (true false)(one true false) -- preferred form(one (true false))

These expressions have type lsquostring bool boolrsquo3 Note that the expression

((one true) false)

has type lsquo(string bool) boolrsquo which makes it strictly type distinct from (incompatiblewith) the previous expression

Note that (in expressions) commas are the loosest binding operator which means that

x y == 3 4

will parse as

(x ((y == 3) 4)) -- fully elaborated form

and not as

(x y) == (3 4) -- this could be what was intended

It is advisable that users only drop brackets when there is little chance of ambiguity3This is the same as lsquostring (bool bool)rsquo

3

16 MapsMaps are used to represent total functions4 For example the declaration

type map nat -gt int -- a map type pseudonym

introduces a type pseudonym for maps with domain lsquonatrsquo and codomain lsquointrsquo Maps and singlemap entries can be assigned to for example given the declaration

declare -- three global maps

m1 mapm2 mapm3 nat -gt nat

the statement m1 lt- m2 m1(1) lt- 2

will set map lsquom1rsquo to be lsquom2rsquo and this map is then updated so that lsquom1(1)rsquo takes value lsquo2rsquoThe language encourages the use of simple un-curried maps which means that the type

type map bool nat -gt int

should be used in preference totype nmap nat -gt inttype map bool -gt nmap

In particular the language does not permit the syntax lsquom(true)(2)rsquo whereas lsquom(true 2)rsquo is fineThe language does not provide a mechanism for specifying anonymous functions or anonymous

maps5 Furthermore maps and operations (either primitive or user defined) are considered to bedistinct As such it is not possible to make assignments of the form lsquom3 lt- Log2rsquo

17 Sum TypesEnumerated and sum (tagged union) types can be introduced using the lsquoconstructrsquo keywordFor example the declaration

construct enumerated Zero One Two Three -- a new type called enumerated

introduces a new type lsquoenumeratedrsquo that consists of four elements (new constants) Sum typescan be declared in a similar manner for example

construct bool_option BoolNone BoolSome bool -- an unnecessary variant of bool option

The elements of this new type are lsquoBoolNonersquo lsquoBoolSome(false)rsquo and lsquoBoolSome(true)rsquo6 Everyconstructor of the sum type must map from a pre-existing type (or be nullary) and this precludesthe definition of new recursive or mutually recursive datatypes

Enumerated types (where every constructor is nullary) admit casting tofrom numeric types7For example lsquo[One]natrsquo is equal to lsquo0n1rsquo and lsquo[0n1]enumeratedrsquo is equal to lsquoOnersquo

4Maps must have an equality type as their domain They can be viewed as a form of array and are typically usedto model memories and register banks

5The function lsquofn x =gt x + 1rsquo is an example of an anonymous function in Standard ML6The brackets are needed here for example lsquoBoolSome truersquo will not parse7The same does not hold for general sum types

4

18 RecordsRecord types can be introduced using the lsquorecordrsquo construct The following is an example of arecord declaration

record rec

number natinteger intboolean bool

Every value of type lsquorecrsquo has three components which may be accessed using dot notation forexample if we have a global variable

declare rec rec

then the sub-elements are lsquorecnumberrsquo lsquorecintegerrsquo and lsquorecbooleanrsquo The language does notprovide a syntax for record literals As such records must be built up incrementally for examplethe following is a sequence of assignments to components of the variable lsquorecrsquo

recnumber lt- 1 recinteger lt- 2 recboolean lt- true

It is not possible to express this with a single assignment to lsquorecrsquo

19 RegistersRegister types can be introduced using the lsquoregisterrsquo construct for example

register sreg bits(32)

31-28 FLAGS7-0 27-16 MODE15-12 MASK

This declares a new type lsquosregrsquo that represents the following 32-bit register31 28 27 16 15 12 11 8 7 0

FLAGS MODElt110gt MASK MODElt1912gt

Note that the bit-field 118 of lsquosregrsquo does not correspond with a named component Also notethat fields are allowed to be non-contiguous which is the case for the lsquoMODErsquo field Register typesare essentially special forms of record types with the automatic specification of bijections toa bit-vector representation Each named bit-field can be accessed using the dot notation forexample if we have

declare status sreg

then the fields lsquostatusFLAGSrsquo and lsquostatusMASKrsquo have type lsquobits(4)rsquo and lsquostatusMODErsquo has typelsquobits(20)rsquo Unlike records register types automatic admit casting tofrom an underlying bit-vector type The expression lsquoampstatusrsquo gives the value of the register (with type lsquobits(32)rsquo) andlsquosreg(0xFFFF0000)rsquo constructs a register of type lsquosregrsquo It is possible to use this notation to updatearbitrary bit-fields of a register for example the statement

ampstatuslt207gt lt- 11101101100111

will update the bit-field 207 of lsquostatusrsquo using the 14-bit literal value

5

110 Polymorphic TypesUsers cannot declare their own polymorphic types Furthermore all user defined operations andvariables must be monomorphic The language does however provide support for three built-inpolymorphic datatypes which may be used under the proviso that these types are always fullytype instantiated (free of type variables)

1101 ListsThe language provides limited support for working with lists Lists can be specified as follows

list 0n0 2 4 -- a list of naturals (length three)0n0 2 3 Nil -- expanded versionCons (0n0 Cons (2 Cons (4 Nil))) -- equivalent version

These expressions have type lsquonat listrsquo Given the first-order nature of L3 only simple listoperations are provided (for example lsquoHeadrsquo lsquoTailrsquo and lsquoLengthrsquo) Higher-order list operationssuch as filter map and fold are not available

1102 Finite SetsThe language provides basic support for finite sets Sets can be specified as follows

set 0n0 2 4 -- a three element set (of naturals)0n0 insert 2 insert 4 insert set -- an expanded versionSetOfList (list 0n0 2 4 ) -- a version built from a list

These expressions have type lsquonat setrsquo The infix operators lsquoinrsquo and lsquonotinrsquo test for set member-ship for example the expressions

0n0 in set 0 2 4 -- test for membership0n1 notin set 0 2 4 -- test for non-membership

both evaluate to lsquotruersquo Sets can only be defined over equality types It is not possible forexample to construct the type lsquo(bool -gt bool) setrsquo

1103 Option TypesThe option type is a polymorphic sum type that has two constructors lsquoNoneα optionrsquo andlsquoSomeαrarrα optionrsquo Option types are helpful when specifying partial operations

111 Statements and ExpressionsThis section presents the statements and expressions of the language Statements can be groupedinto blocks using the syntax

statement1 -- do thisstatement2 -- then do thismiddot middot middot

6

Each block and sub-statement has type lsquounitrsquo The operator lsquorsquo is strictly binary trailing semi-colons not permitted at the end of a sequence of statements Expressions are distinct fromstatements in particular expressions preclude assignments

1111 NothingThe statement lsquonothingrsquo has no effect Its primary purpose is to facilitate the specification ofcontrol flows wherein some paths do something (update the state) and others do nothing8

1112 ConditionalsThe language supports if-then-else statements and expressions and when-do statements Thelatter is provided as a convenient shorthand that is to say the statement

when p do x

is equivalent to the statement

if p then x else nothing

Note that the language does not support layout syntax (the off-side-rule)

1113 For LoopsThe language provides support for simple for-loop statements On each iteration of a for-loopa natural number index variable is either incremented or decremented (by one) This process isrepeated until the index value reaches a pre-computed upper or lower bound for example theloop statements

for i in 1 3 do proc(i)for i in 3 1 do proc(i)

are respectively equivalent to

proc(1) proc(2) proc(3) proc(3) proc(2) proc(1)

The initial and final loop index values may be arbitrary natural number expressions As suchit may be the case that the loop direction will only be known once these bound expressions arecomputed

In addition to regular for loops the language also supports foreach loops which operate overlists For example the following code makes three calls to lsquoprocrsquo

foreach i in list 0n2 4 6 do proc(i)

Note that this construct will also work for bit-strings and for normal stringsThere is no support for do while or repeat until loops

8The lsquonothingrsquo statement is essentially syntactic sugar for lsquo()rsquo

7

1114 Exceptions Unknown and UndefinedThe keyword lsquoUNKNOWNrsquo is used to represent an unspecified element which may be of any giventype The language does not stipulate whether or not this value should be chosen deterministi-cally If the value were chosen deterministically then the expression lsquoUNKNOWN == UNKNOWNrsquo willalways be lsquotruersquo However if the choice is non-deterministic then there is no way of knowing ifan occurrence of this expression is lsquotruersquo or lsquofalsersquo

The language supports user defined exceptions which may be raised but not caught Thelsquoexceptionrsquo keyword is used to declare new exception categories for example

exception ASSERT string

introduces a new exception lsquoASSERTrsquo that takes a single string as an argument This exception canbe raised in expressions and statements as follows

ASSERT (an error has occurred)

Thus exceptions can be used to flag the occurrence of a variety of different errors The L3interpreter will stop when an exception is raised Exceptions can be raised within expressionsand are not constrained by return type

The behaviour of various operations is undefined on some inputs for example the arithmeticexpression lsquox div 0n0rsquo is undefined For any given undefined expression the language permitsthree possible interpretations (implementations)

bull A deterministic value can be chosen For example lsquox div 0n0rsquo is equal to lsquo0n0rsquo is a validinterpretation of this undefined expression

bull A non-deterministic value can be chosen In particular is not necessary for the expressionlsquox div 0n0 == x div 0n0rsquo to be lsquotruersquo

bull An exception can be raised

It is expected that specifications will be designed with some preferred treatment of undefinedbehaviour in mind In this example one possible way to manage undefined cases is by takingcare to explicitly write code of the form lsquoif n == 0 then else x div n rsquo This willensure that undefined cases are unreachable

1115 Procedure CallsA procedure is any user defined operation with return type lsquounitrsquo Procedures typically providefunctionality by means of updating the global state (through side effects) Procedures can becalled (and exceptions can be raised) in statement blocks for example

middot middot middotproc (1 true) -- this is a procedure callmiddot middot middot

The following code is valid but not recommended

8

middot middot middotASSERT error -- raise an exceptionproc (1 true) -- the L3 interpreter will never reach this code

In the above the exception is unconditionally raised so the remaining code should be regardedas unreachable (redundant)

1116 Local VariablesThe L3 language supports two varieties of variables mutable and immutable All global vari-ables are mutable The keyword lsquovarrsquo is used to declare new mutable variables with local scopeLocal variables can be introduced anywhere within a statement block and these variables canbe assigned to using the lsquolt-rsquo operator Immutable variables are introduced within a block usingthe syntax lsquox = expr rsquo and this is treated as a let-statement An immutable value cannot beupdated however it can fall out of scope by declaring a new immutable variable with the samename The operators lsquolt-rsquo and lsquo=rsquo are not permitted in expressions

The specification below uses two mutable variables lsquoxrsquo and lsquoyrsquo

var y = zvar x = yif p then xlt30gt lt- 1111 y lt- x + 1

else xlt74gt lt- 1111 y lt- 0 return (x + y)

This could be respecified using immutable variables for example

y = zx = yx y = if p then (x || 00001111 x || 00001111 + 1)

else (x || 11110000 0)return (x + y)

It is not always easy to eliminate mutable variables In this case the second specification ismore cumbersome because the bit-field update has been replace by an explicit mask (bitwise-or)operation This operations has been repeated in specify the value of lsquoyrsquo because assignments arenot permitted in expressions

Mutable variables can be declared without an initial assignment for example lsquovar xrsquo isequivalent to lsquovar x = UNKNOWNrsquo

1117 PatternMatchingThe language supports match statements and expressions Pattern matching is supported withrespect to literals (see Section 13) constructors9 (immutable) variables wildcards (anonymousvariables) and bit-patterns

9This includes matching on tuples as well as lsquoNonersquo lsquoSomersquo lsquoConsrsquo and lsquoNilrsquo Matching on finite sets and recordfields is not possible

9

Given the type declarations

construct enum One Two Three construct data

NoDataData1 string bits(8)Data2 enum bits(16)

the following illustrates a match expression

match y

case -1 NoData or -2 NoData =gt 0`4 -- note use of orcase _ Data1 (hello 11 x 11) =gt x + 1 -- use of bit-patterncase i Data2 (Three 1111 y) =gt [i] + ylt30gtcase 1 Data2 (_ 8) =gt 4case _ =gt 8

The body (right-hand side of lsquo=gtrsquo) of the first case line with a matching pattern is selected Thesymbol lsquo_rsquo is a wildcard and will match any value The lsquoorrsquo construct provides a shorthand forwriting blocks of clauses with differing patterns but the same body

The terms lsquo11 x 11rsquo and lsquo1111 yrsquo are called bit-patterns and they will match against a setof bit-vector values From the type declaration of lsquodatarsquo it is known that the variable lsquoxrsquo mustrepresent a 4-bit value because it occurs in the middle of an 8-bit word (the match requires bitslsquo11rsquo as a prefix and as a suffix) Likewise lsquoyrsquo must be a 12-bit value Multiple variables can occurin a bit-patterns for example lsquo1 x 1 y 0rsquo is a valid bit-pattern The type checker will oftenbe able to infer the type of pattern variables and if this fails type annotations can be added

The lsquopatternrsquo construct can help avoid situations where explicit annotations are repeatedlyrequired (causing clutter in patterns) If for example the variable lsquoimm5rsquo is frequently used tomatch a 5-bit value then the following declaration can be made

pattern imm5 bits(5)

In subsequent code the default type for pattern variable lsquoimm5rsquo will be lsquobits(5)rsquo The lsquopatternrsquoconstruct only influences type checking If a particular type hint is no longer appropriate thenit can be dropped for example one can insert the declaration lsquoclear pattern imm5rsquo

112 Defining Constants and OperationsUsers can construct operational semantics style formal specifications in L3 by defining their ownconstants and operations There is no module system or facility for local definitions all userdefinitions are made at the top-level with global scope User constants and operations cannot beoverloaded or redefined

A pure constant is a nullary (zero argument) operation that is state independent for examplethe following code declares a new constant

bits(32) UINT_MAX = 0xFFFFFFFF

10

The following code declares operations that are nullary but state dependent

declare number Natnat numberPlus1 = return (number + 1)unit incNumber = number lt- numberPlus1

Users can also declare new unary operations which may or may not be state dependent forexample

nat numberMinusN (nnat) = return (number + n) -- state dependentunit decNumber () = number lt- numberMinusN (1)nat mla (mnatnnatanat) = return (m n + a) -- pure

The operation lsquomlarsquo is unary because it takes a single triple as an argument To enhance clarityand avoid misunderstandards users may elect to specify nullary state dependent operations usinga single lsquounitrsquo argument Given the declarations above the expression lsquodecNumber()rsquo gives theclear impression that a call is being made (with possible side-effects) wheres the expressionlsquoincNumberrsquo does not

At the point of declaration operation arguments must be fully type annotated and onlymonomorphic types are allowed10 It is nevertheless possible to declare bit-vector operationsthat are valid with respect to some given set of bit widths for example the following are validdeclarations

--- valid for any bit-vector width N ---bits(N) bv_mla (mbits(N) nbits(N) abits(N)) = return (m n + a)

--- valid for sufficiently wide bit-vectors (N greater than eight) ---bool bit8 (xbits(N)) with N gt 8 = return (xlt8gt)

An L3 type error will arise if ever an application of the operation lsquobit8rsquo violates the bit widthconstraint Note that vector width variables (such as lsquoNnatrsquo above) can be used as if they werea regular variables in the definitional body of an operation

113 ComponentsWhen specifying instruction set architectures the two most significant programmerrsquos modelcomponents are typically the main memory and a collection of general purpose registers In theMIPS architecture for example there are thirty-two general purpose registers which may berepresented using the following map

declare gpr bits(5) -gt bits(64)

The statement

gpr(d) lt- gpr(r)10An compile time error will arise if the type checker is not able to infer all types the final definition must be

free of type variables

11

then expresses moving a value from register lsquorrsquo to register lsquodrsquo However register a memory accessis frequently more complicated than this in particular registers can be banked and memory canbe complex11 As such it is often necessary to specify collections of operations for accessing(reading and writing) these components With the MIPS example register zero is special (it isa constant value) and so one could define the following operations

bits(64) read_gpr (nbits(5)) = if n == 0 then 0 else gpr (n)unit write_gpr (vbits(64) nbits(5)) = when n ltgt 0 do gpr (n) lt- v

Thus the previous register transfers would now be specified as follows

write_gpr (read_gpr (n) d)

This precise style of specification is not entirely satisfying though since it departs in appearancefrom the pseudo code found in MIPS reference manuals The L3 language provides a specialmechanism for specifying a pair of operations that read and write state components With theMIPS example the following declaration can be made

component GPR (nbits(5)) bits(64)

value = if n == 0 then 0 else gpr(n)assign value = when n ltgt 0 do gpr(n) lt- value

One can then write

GPR(d) lt- GPR(r)

which is closer to the syntax used in the MIPS reference manuals The lsquocomponentrsquo constructeffectively provides a controlled form of operator overloading whereby the lsquoassignrsquo operation12

is select when the operator name appears on the left-hand side of an assignment (lsquolt-rsquo) and thelsquovaluersquo operation13 is applied otherwise Semantically these two operations are exactly the sameas the manually defined versions lsquowrite_gprrsquo and lsquoread_gprrsquo The ldquowriterdquo operation will alwayshave a lsquounitrsquo return type Users are free to specify the ldquoreadrdquo and ldquowriterdquo operations in any mannerthat they deem appropriate however the ldquowriterdquo operation cannot be defined recursively norcan the ldquoreadrdquo operation call the ldquowriterdquo operation

114 RecursionThe language permits the definition of recursive operations It is not possible to define mutuallyrecursive operations

The L3 language has been designed to act as an authoring front-end for the HOL4 theoremprover facilitating the task of writing instruction set specifications In order to successfullyimport an L3 specification it is necessary for the HOL4 system to prove that every user defined

11ARM registers are banked according to processor mode Memory can often be accessed with big- and little-endian byte ordering Special treatment may be needed for unaligned memory addresses for example when readinga 16-bit value from an odd address There may also be address translation (virtualisation) and memory hierarchies(caching)

12In this example the ldquowriterdquo operations is internally called lsquowriteGPRrsquo13Internally the ldquoreadrdquo operation is simply called lsquoGPRrsquo

12

operation is total (terminates on all inputs) If an L3 function is non-terminating then it willbe impossible to export that definition to HOL4 If a function is terminating but the standardautomation of HOL4 is unable to construct a termination proof then it may be necessary toprovide the prover with a hint in the form of a measure

Consider the following specification

declare m bits(8) -gt bits(8)

unit load (abits(8) lbits(8) list) =match l

case Nil =gt nothingcase Cons (h t) =gt m(a) lt- h load (a + 1 t)

The lsquoloadrsquo operation recurses over the list lsquolrsquo loading values into the map lsquomrsquo At the time ofwriting this documentation trying to build the exported HOL4 version of this specificationgives rise to the following error message

Initial goal

existRWF R andforallstate a l h t

(l = ht) rArrR ((a + 1wt)state with m = (a =+ h) statem) ((al)state)

Exception raised at TotalDefnDefinebetween beginning of frag 0 and end of frag 0at TotalDefndefnDefine

Unable to prove termination

Try using TotalDefntDefine ltnamegt ltquotationgt lttacgt

This occurs because HOL4 is unable to automatically prove that lsquoloadrsquo always terminates Toget around this problem the original L3 specification can be modified to contain an annotationas follows

unit load (abits(8) lbits(8) list) measure Length(l) =

The metadata lsquomeasure Length(l)rsquo tells HOL4 to examine the length of the list lsquolrsquo since thisvalue will decrease upon each recursive call to lsquoloadrsquo When the length of the list is zero (thelsquoNilrsquo case) there are no recursive calls so termination is guaranteed

The expression occurring after the lsquomeasurersquo keyword must be of type lsquonatrsquo After provid-ing a measure it is still possible that HOL4 will fail to prove termination either because thesupplied measure is incorrect or because the termination proof is non-trivial (requires humanguidance andor custom lemmas) If this occurs then users should either simplifyrewrite theirspecifications or if necessary report the problem

13

115 Instruction Set DefinitionsWhen working with instruction set models it is helpful to construct a datatype that representsthe set of machine (low-level) instructions This datatype constitutes a simple form of abstractsyntax tree (AST) and it can be used to build instruction decoders (identifying machine-codeinstructions and splitting opcodes into sub-fields) instruction encoders (generating opcodes fora given instruction) next-state functions (applying a semantics function for a given instruction)and assembly code parsers

By way of an example consider the MIPS instruction ANDI this instruction has the assemblycode syntax

ANDI rt rs immediate

and the following 32-bit machine-code encoding

31 26 25 21 20 16 15 0

001100 rs rt immediate6 5 5 16

The semantics of this instruction can be expressed with the operation

unit run_ANDI (rsbits(5) rtbits(5) immbits(16)) =GPR(rt) lt- GPR(rs) ampamp ZeroExtend (imm)

One could use this operation to directly specify a next-state function which would be of theform

unit Next =match Fetch -- fetches a 32-bit opcode from memory

middot middot middotcase 001100 rs rt imm =gt run_ANDI (rs rt imm)middot middot middot

This style of specification is direct and concise however it does lack some of the flexibility thatcomes with using an instruction datatype The L3 language provides support for an slightlydifferent style of specification This alternative approach is explained by first examining howone would specify things manually (explicitly) and then showing how L3 can streamline thisprocess

Firstly one could explicitly define an AST datatype for MIPS instructions it would be ofthe form

construct instruction

middot middot middotANDI bits(5) bits(5) bits(16)middot middot middot

14

This datatype provides a suitable constructor for the ANDI instruction It is now possible to definea decoder which maps opcodes onto AST entries for example

instruction Decode (opcbits(32)) =match opc

middot middot middotcase 001100 rs rt imm =gt ANDI (rs rt imm)middot middot middot

This decoder can be used to define our next-state function that is

unit Next = Run (Decode (Fetch))

where lsquoRunrsquo is defined by

unit Run (iinstruction) =match i

middot middot middotcase ANDI (args) =gt run_ANDI (args)middot middot middot

When working with full-scale architecture specifications (where the AST type is large) thereare some clear overheads associated with implementing this approach (in comparison with theAST free version) It becomes challenging to maintain the AST datatype declaration and tokeep it correctly synchronised with the instruction semantics operations (such as lsquorun_ANDIrsquo)and the definition of lsquoRunrsquo Note however that there is great uniformity in the AST datatypedeclaration and also in the definition of lsquoRunrsquo As such L3 is able to automatically define bothof these for the user

To make use of this automation the declaration of lsquorun_ANDIrsquo is simply modified to

define ANDI (rsbits(5) rtbits(5) immbits(16)) =GPR(rt) lt- GPR(rs) ampamp ZeroExtend (imm)

The lsquodefinersquo keyword tells L3 to define a semantics function14 (as before) and to also create anew lsquoinstructionrsquo datatype AST entry furthermore the two will be linked with the automaticconstruction of a lsquoRunrsquo function The lsquoinstructionrsquo type and lsquoRunrsquo function become defined (inscope) following the declaration lsquodefine Runrsquo After this declaration it is no longer possible touse the lsquodefinersquo construct again however it does become possible to define functions such aslsquoDecodersquo and lsquoNextrsquo

Specifications that are based on using lsquodefinersquo gain the benefits of declaring an instructionAST datatype without the downside of laborious coding overheads In the example above theoverhead amounts to one extra line of code this comes from defining a next-state function thatcalls the dedicated decode function followed by a call to lsquoRunrsquo

One of the key advantages of declaring an instruction datatype is that it makes it consider-ably easier to develop tools that work with assembly code syntax (performing parsing encoding

14This function is internally called lsquodfnANDIrsquo instead of lsquorun_ANDIrsquo

15

and pretty-printing) In this case it is relatively easy for example to map between the MIPSinstruction syntax andi $5 $6 1024 and the expression lsquoANDI (5 6 1024)rsquo Defining anencoder in L3 is relatively straightforward for example

bits(32) Encode (iinstruction) =match i

middot middot middotcase ANDI (rs rt imm) =gt 001100 rs rt immmiddot middot middot

Such a function can be used to write a MIPS assembler which would map the assembly codesyntax andi $5 $6 1024 onto the machine-code value 0x30c50400

2 TutorialThis section gives a brief overview of how to install and use L3

Installation The sources for L3 can be downloaded from the following webpage

wwwclcamacuk~acjf3l3

The file l3tarbz2 can be unpacked with the command

$ tar xvjf l3tarbz2

This will create a directory of the form L3-YYYY-MM-DD where the year month and day willcorrespond with the release date The current version of L3 depends upon PolyML 57 whichcan be obtained from the site polymlorg If PolyML is installed then L3 can be built as follows

$ cd L3-YYYY-MM-DD$ make

Once built the following should appear when you start L315

$ l3ltlt L3 gtgtgt

Users should consider running L3 with the command rlwrap l316

15This assumes that the directory L3-YYYY-MM-DDbin has been added to the PATH environment variable16Details on rlwrap utility can be found at the site freecodecomprojectsrlwrap

16

Basic Interaction The command prompt for L3 is essentially the read-eval-print loop (REPL)of PolyML As such users are free to write arbitrary Standard ML code The structure Runtimeenables interaction with L3 The following shows an arithmetic evaluation in Standard ML aswell as in the L3 interpreter (evalQ)

gt 1 + 2val it = 3 intgt RuntimeevalQ `0i1 + 2`val it = `0i3` Termterm

Various error messages can occur when using the interpreter for example

gt RuntimeevalQ `1 + 2`Exception- Fail Could not infer all types raised

gt RuntimeevalQ `0i2 div 0`Exception- Except (Div SOME (div (int [`0i2` `0i0`]))) raised

The first error occurs because unannotated number literals are regarded as bit-vector values andhere the vector width cannot be inferred

L3 declarations can be made using the function loadQ The following sequence shows thedeclaration and manipulation of a global variable

gt RuntimeloadQ `declare n nat`ltVARgt nval it = () unit

gt RuntimeevalQ `n`val it = `UNKNOWNnat` Termterm

gt RuntimeevalQ ` n lt- 3 n `val it = `0n3` Termterm

The global state can be examined using the function show for example

gt Runtimeshow()val it = [(n `0n3`)] Evalterm_stack

The state can be ldquowipedrdquo clean using the function reset and all declarations can be wiped usinglsquoresetAllrsquo for example

gt Runtimereset()val it = () unitgt Runtimeshow()val it = [(n `UNKNOWNnat`)] Evalterm_stack

gt RuntimeresetAll()val it = () unitgt Runtimeshow()val it = [] Evalterm_stack

The function lsquoLoadQrsquo is similar to lsquoloadQrsquo but it performs a lsquoresetAllrsquo before making declarations

17

Constants The structure Consts provides various functions for working with L3 constantsMany of the operation in the Consts structure will be of little interest to end-users however itcan be used to display some helpful information

The function ConstslookupConst can be used to lookup an operation for example

gt ConstslookupConst Log2val it = Primitive [(bits(a) -gt bits(a) -) (nat -gt nat -)] const

Since lsquoLog2rsquo is a primitive operation only the valid types (ordered by overload priority) are showWith user operations the internal representation (definition) of the operation will be shownfor example

gt RuntimeLoadQ `unit demo () = ()`gt ConstslookupConst demoval it = Definition (Abs ([(_ (unit -))] unit -gt unit `()`) NONE 1)

Constsconst

The functions ConstslistDefinitions and ConstslistExceptions provide details of all useroperations and exceptions respectively The function lsquoConstsstatsrsquo gives a summary of all thecurrent declarations

gt Constsstats()Primitives 188Destructors 5Constructors 0Accessors 0Exceptions 0User operations 1Instruction definitions 0

Here the constructors for primitive types (such as lsquoConsrsquo) are counted under ldquoprimitivesrdquo

Types The Types structure can be used to display information relating to L3 types In partic-ular this structure provides the functions TypeslookupConst and TypeslistConsts which aredemonstrated below

gt RuntimeloadQ `construct enum One Two Three`gt TypeslistConsts()val it =

[(enumeq = true ast = false def = Constructors (Enum ltdict(3)gt) num = 0)]

(string typeconst) list

gt TypeslookupConst intval it = SOME eq = true ast = false def = BaseType num = ~1

typeconst option

18

Loading and Exporting Specifications When writing an L3 specification it is expected thatuser declarations will be contained in an L3 source file A sample instruction set specification(tinyspec) can be found in the L3 distribution subdirectory examples This specification isbased on Thackerrsquos pedagogical Tiny 3 architecture it can be loaded as follows

gt RuntimeLoadF tinyspecLoading tinyspecltTYPgt regTltTYPgt wordTmiddot middot middotltFUNgt test_progDone

The string argument to the functions RuntimeloadF and RuntimeLoadF can be in the form ofa comma separated list of files which will be loaded in order That is the call

RuntimeloadF aspec bspec

will load aspec followed by bspecThe function HolExportexport will export the current L3 specification in the form of an

HOL4 script for example

gt HolExportexport tinyraiseexception okfunction okmiddot middot middotmextend skipmunextend skipCreated file tinyScriptsmlCreated file tinyLibsmlCreated file tinyLibsigDone

The function HolExportspec provides a convenient shortcut for performing LoadF and exportusing just a single call for example HolExportspec (tinyspec tiny) will perform theload and export presented above

L3 is capable of exporting two styles of HOL specification an explicitly monadic version(based on state_transformerTheory) and a version that directly manipulates state using let-expressions (which is the default style) For example a monadic version of the Tiny specifi-cation can be exported using the command HolExportspec (tinyspec tiny monadic)Other export options include sigdocs nosigdocs (for setting HOLrsquos TheoryPPinclude_docstrace variable) bigrecords nobigrecords (for controlling HOLrsquos Datatypebig_record_size)and underflowbefore nounderflowbefore (for selecting the required IEEE 754 underflow be-haviour)

Generated HOL4 specifications are not designed to be manually edited (or human readable)To build an L3 specification script the HOL library Import is needed This library is currentlylocated in the directory $HOL_DIRexamplesl3-machine-codecommon and so adding this path tothe INCLUDES variable of a local Holmakefile is recommended The examplesl3-machine-codedirectory contains various examples of using L3 generated specifications

19

Testing Specifications Having written an L3 specification it is fairly easy to write code (inStandard ML) that runs test vectors Code for running the tinyspec example can be found inthe file run-tinyspec In this test harness the Tiny state is initialised and a small test programis loaded simply by evaluating the expression lsquoinitialize (test_prog)rsquo

It is also possible to evaluate (run) models that have been exported to HOL4 The filerun-tinysml shows how this can be accomplished for the Tiny example

20

A Primitive Types and OperationsThe primitive types are as follows

unit bool char nat int bits(middot) rounding

There are two infix type constructors lsquorsquo for pairs and lsquo-gtrsquo for maps There are also postfix typeconstructors lsquosetrsquo lsquooptionrsquo and lsquolistrsquo for example sets of strings are represented by the typelsquostring setrsquo The following sections describe these primitive types together with some detailsof associated operations The following constants and operations are available

nullary () Nil None false roundTiesToEven roundTowardNegativeroundTowardPositive roundTowardZero true

prefix - ~ Abs Cardinality Cons Difference Drop Element FP32_AbsFP32_Add FP32_Equal FP32_IsNan FP32_LessThan FP32_MulFP32_Neg FP32_Sub FP64_Abs FP64_Add FP64_Equal FP64_IsNanFP64_LessThan FP64_Mul FP64_Neg FP64_Sub FromBinStringFromDecString FromHexString Fst Head IndexOf InitMapIntersection IsAlpha IsAlphaNum IsDigit IsHexDigit IsLowerIsMember IsSome IsSubset IsUpper Length Log2 Max Min MsbQuotRem Remove RemoveDuplicates RemoveExcept ReverseSetOfList SignExtend SignedMax SignedMin Size Snd Some TailTake ToLower ToUpper Union Update ValOf ZeroExtend not

infix = ampamp + - lt lt+ lt= lt=+ ltgt == gt gt+ gt= gt=+ ^ || gtgtltlt gtgt+ ltlt gtgt and div in insert mod notin or quot rem

sdivsmodother middot ltmiddotgt middot ltmiddotmiddotgt [middot] fields splitl splitr tokens

Many arithmetic operations are overloaded Unless otherwise stated the order of selection islsquobits(middot)rsquo lsquonatrsquo lsquointrsquo and then lsquobool listrsquo

A1 UnitThe type lsquounitrsquo represents the singleton set containing the value lsquo()rsquo The primary use of thistype is as the return type for procedures

A2 BoolThe type lsquoboolrsquo represents the two element set B = lsquotruersquo lsquofalsersquo The following standardBoolean operations are available

negation not bool rarr boolconjunction and booltimes bool rarr booldisjunction or booltimes bool rarr boolequality == αtimesα rarr boolnon-equality ltgt = αtimesα rarr bool

21

The infix operators lsquoandrsquo and lsquoorrsquo are interpreted with short-circuit evaluation for example in theexpression lsquofalse and f()rsquo the value of lsquof()rsquo is not computed as the overall expression will alwaysevaluate to false This short-circuiting influences the side-effects that occur during expressionevaluation

There are two prefix symbols for logical negation (these are semantically identical) with lsquorsquobinding slightly tighter than lsquonotrsquo This distinction is becomes significant when working withequalities for example lsquonot a == brsquo is taken to be not(a = b) whereas lsquoa == brsquo is (nota) = b

Equality is only defined with respect to equality types represented here by the type variableα An equality type is any type built without the used of the map operator lsquo-gtrsquo

A3 NatThe type lsquonatrsquo represents the natural numbers N = 0 1 2 The following operations areavailable

logarithm (base two) Log2 nat rarr natminimum value Min nattimes nat rarr natmaximium value Max nattimes nat rarr natless than lt nattimes nat rarr boolgreater than gt nattimes nat rarr boolless than or equal to lt= nattimes nat rarr boolgreater than or equal to gt= nattimes nat rarr booladdition + nattimes nat rarr natsubtraction - nattimes nat rarr natmultiplication nattimes nat rarr natexponentiation nattimes nat rarr natdivision div nattimes nat rarr natmodulus mod nattimes nat rarr nat

The lsquodivrsquo and lsquomodrsquo operations satisfy the following property

foralln 0 lt n =rArr forallk k = (k div n) lowast n+ (k mod n) and (k mod n) lt n

The expressions lsquoLog2(0)rsquo lsquox div 0rsquo and lsquox mod 0rsquo are all undefined 17

A4 IntThe type lsquointrsquo represents the integers Z = Ncupminus1minus2minus3 The following operations areavailable

17The interpreter will raise an exception when attempting to evaluate them

22

unary minus - int rarr intabsolute value Abs int rarr intminimum value Min inttimes int rarr intmaximum value Max inttimes int rarr intless than lt inttimes int rarr boolgreater than gt inttimes int rarr boolless than or equal to lt= inttimes int rarr boolgreater than or equal to gt= inttimes int rarr booladdition + inttimes int rarr intsubtraction - inttimes int rarr intmultiplication inttimes int rarr intexponentiation inttimes nat rarr intquotient and remainder QuotRem inttimes int rarr inttimes intquotient quot inttimes int rarr intremainder rem inttimes int rarr intdivision div inttimes int rarr intmodulus mod inttimes int rarr int

The operation lsquoAbsrsquo gives an positive integer value for example lsquoAbs(-2)rsquo = lsquo2rsquo The integeroperations lsquoquotrsquo and lsquodivrsquo are related to natural number division as follows

i quot j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

and

i div j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(minusi) div n(j))minus 1 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i and n(i) mod n(minusj) = 0

minus z(n(i) div n(minusj))minus 1 j lt 0 and 0 le i and n(i) mod n(minusj) = 0

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

where z NrarrZ and n ZrarrN are value preserving maps The lsquoremrsquo and lsquomodrsquo operations satisfythe equations

i rem j =

iminus (i quot j) lowast j j = 0

undefined j = 0i mod j =

iminus (i div j) lowast j j = 0

undefined j = 0

A5 Bit-vectorsThe type lsquobits(n)rsquo represents fixed-width (n-bit) words also known as bit-vectors for examplebits(32) is the type of 32-bit machine words18 The bits type can be viewed as representing

18These are called double-words (dword) in the x86 architecture and simply words in the ARM architecture

23

the set Zn = 0 1 2nminus1 for some 0 lt n At the type system level no distinction is madebetween signed and unsigned words however some operations (such as orderings) have signedand unsigned variants

The following bit-vector operations are available

1rsquos complement ~ bits(n) rarr bits(n)2rsquos complement - bits(n) rarr bits(n)absolute value Abs bits(n) rarr bits(n)logarithm (base two) Log2 bits(n) rarr bits(n)zero-extend ZeroExtend bits(m) rarr bits(n)sign-extend SignExtend bits(m) rarr bits(n)reverse bits Reverse bits(n) rarr bits(n)minimum value (u) Min bits(n)times bits(n) rarr bits(n)maximum value (u) Max bits(n)times bits(n) rarr bits(n)minimum value (s) SignedMin bits(n)times bits(n) rarr bits(n)maximum value (s) SignedMax bits(n)times bits(n) rarr bits(n)widthsize Size bits(n) rarr natmost-significant (sign) bit Msb bits(n) rarr boolbit value middot ltmiddotgt bits(n)times nat rarr boolbit field middot ltmiddotmiddotgt bits(m)times nattimes nat rarr bits(n)concatenation bits(m)times bits(n) rarr bits(p)duplication ^ bits(m)times nat rarr bits(n)less than (s) lt bits(n)times bits(n) rarr boolgreater than (s) gt bits(n)times bits(n) rarr boolless than or equal to (s) lt= bits(n)times bits(n) rarr boolgreater than or equal to (s) gt= bits(n)times bits(n) rarr boolless than (u) lt+ bits(n)times bits(n) rarr boolgreater than (u) gt+ bits(n)times bits(n) rarr boolless than or equal to (u) lt=+ bits(n)times bits(n) rarr boolgreater than or equal to (u) gt=+ bits(n)times bits(n) rarr booladdition + bits(n)times bits(n) rarr bits(n)subtraction - bits(n)times bits(n) rarr bits(n)multiplication bits(n)times bits(n) rarr bits(n)quotient (s) quot bits(n)times bits(n) rarr bits(n)remained (s) rem bits(n)times bits(n) rarr bits(n)division (u) div bits(n)times bits(n) rarr bits(n)modulus (u) mod bits(n)times bits(n) rarr bits(n)division (s) sdiv bits(n)times bits(n) rarr bits(n)modulus (s) smod bits(n)times bits(n) rarr bits(n)bitwise conjunction ampamp bits(n)times bits(n) rarr bits(n)bitwise disjunction || bits(n)times bits(n) rarr bits(n)bitwise exclusive-or bits(n)times bits(n) rarr bits(n)

Unsigned operations are labelled with (u) and signed operations are labelled with (s)The shift operations support shifting by either a bit-vector value or by a natural number value

The overloading is resolved such that the lsquonatrsquo variant is selected over the lsquobits(middot)rsquo version Theshift operations are

24

left-shift ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (u) gtgt+ bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (s) gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate left ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate right gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

A number of operations are undefined depending on the types of their domain and rangeThis is detailed in the following table

Operation Undefined when

ZeroExtend(x`n)`m m lt nSignExtend(x`n)`m m lt n(x`m)ltpgt m le p(x`m)lthlgt`n n = h+ 1minus l or h lt l orm le h((xm) (yn))`p p = m+ n((x`m) ^ n)`p p = m middot n (which covers n = 0)

The type checker will fail when these conditions are obviously violated Alternatively the inter-preter may raise a runtime error when these conditions are not met

As before the expressions lsquoLog2(0)rsquo lsquox quot 0rsquo lsquox rem 0rsquo lsquox div 0rsquo and lsquox mod 0rsquo are allundefined

A6 Bit-stringsVarious bit-string operation are defined over the type lsquobool listrsquo These are listed below

bit value middot ltmiddotgt bool listtimes nat rarr boolbit field middot ltmiddotmiddotgt bool listtimes nattimes nat rarr bool listconcatenation bool listtimes bool list rarr bool listduplication ^ bool listtimes nat rarr bool listaddition + bool listtimes bool list rarr bool listbitwise conjunction ampamp bool listtimes bool list rarr bool listbitwise disjunction || bool listtimes bool list rarr bool listbitwise exclusive-or bool listtimes bool list rarr bool listleft-shift ltlt bool listtimes nat rarr bool listright-shift gtgt+ bool listtimes nat rarr bool listrotate-right gtgt bool listtimes nat rarr bool list

The bit value operation gives the truth value of a bit-string at a given bit position for example

lsquo0s1101lt0gtrsquo = lsquotruersquo lsquo0s1101lt1gtrsquo = lsquofalsersquo lsquo0s1101lt2gtrsquo = lsquotruersquolsquo0s1101lt3gtrsquo = lsquotruersquo lsquo0s1101lt4gtrsquo = lsquofalsersquo lsquo0s1101lt5gtrsquo = lsquofalsersquo

25

The least-significant bit (position zero) occurs to the right of the bit-string The bit value oper-ation gives lsquofalsersquo when the bit position is greater than the size of the bit-string

The bit field operation extracts a range of bits from a bit-string For example

lsquo0s1101lt31gtrsquo = lsquo0s110rsquo and lsquo0s1101lt52gtrsquo = lsquo0s0011rsquo

In the bit-string expression xlthlgt the size of the result is always h + 1 minus l and the result isundefined when h lt l

Bit-string addition does not require the arguments to be of the same size and it gives anon-truncated result For example

lsquo0s101 + 0s1rsquo = lsquo0s110rsquo and lsquo0s101 + 0s11rsquo = lsquo0s1000rsquo

The operation ltlt performs a left-shift for example lsquo0s1101 ltlt 2rsquo = lsquo0s110100rsquo The oper-ation lsquorsquo is bit-string concatenation and lsquo^rsquo is duplication for example

lsquo0s101 0s11rsquo = lsquo0s10111rsquo and lsquo0s101 ^ 3rsquo = lsquo0s101101101rsquo

Regular list operations work as one would expect over bit-strings for example lsquoHead (0s101)rsquois a valid expression with value lsquotruersquo

A7 Characters and StringsThe following built-in functions are available for characters and strings

is alphabetic IsAlpha char rarr boolis alpha-numeric IsAlphaNum char rarr boolis decimal digit IsDigit char rarr boolis hexadecimal digit IsHexDigit char rarr boolis lowercase IsLower char rarr boolis uppercase IsUpper char rarr boolparse binary FromBinString string rarr num optionparse decimal FromDecString string rarr num optionparse hexadecimal FromHexString string rarr num optionconvert to lowercase ToLower string rarr stringconvert to uppercase ToUpper string rarr string

The following string operations are useful for parsing

split from the left splitl (char rarr bool) times string rarr string times stringsplit from the right splitr (char rarr bool) times string rarr string times stringsplit into fields fields (char rarr bool) times string rarr string listsplit into tokens tokens (char rarr bool) times string rarr string list

These are based on the SML functions Substringsplitl Substringsplitr Stringfieldsand Stringtokens Character predicates are declared using special syntax for example theexpression

splitl space or hexdigit and not in set a f ( 12bcab)

gives the result lsquo( 12bc ab)rsquo

26

A8 Floating-pointThe L3 language does not provide specialised types for representing floating-point numbersHowever 32-bit (single precision) and 64-bit (double precision) bit-vector values can be treatedas floating-point numbers the following IEEE compliant encoding formats are assumed

31 30 23 22 0

s e m1 8 23

63 62 52 51 0

s e m1 11 52

Here lsquosrsquo is the sign bit (set to lsquo1rsquo for negative numbers) lsquoersquo is a biased exponent value and lsquomrsquo is thesignificand The following constants and operations are available (where lsquofprsquo stands for bits(32)or bits(64) depending on the name of the operation)

rounding modes roundTiesToEvenroundTowardPositiveroundTowardNegativeroundTowardZero

ieee_rounding

flags (record) DivideByZero InvalidOpOverflow PrecisionUnderflow

ieee_flagsrarrbool

comparison values FP_LT FP_EQ FP_GT FP_UN ieee_compare

convert format FP32_ToFP64 fp32rarrfp64convert format FP64_ToFP32 ieee_roundingtimes fp64rarrfp32convert format FP64_ToFP32_ ieee_roundingtimes fp64rarr

ieee_flagstimes fp32from integer FP32|64_FromInt ieee_roundingtimes intrarrfpto integer FP32|64_ToInt ieee_roundingtimes fprarrint optionfrom string FP32|64 stringrarrfp

negative zero FP32|64_NegZero fppositive zero FP32|64_PosZero fpnegative infinity FP32|64_NegInf fppositive infinity FP32|64_PosInf fpa quiet NaN FP32|64_qNan fpa signalling NaN FP32|64_sNan fp

is integral FP32|64_IsIntegral fprarrboolis finite FP32|64_IsFinite fprarrboolis NaN FP32|64_IsNan fprarrboolis signalling NaN FP32|64_IsSignallingNan fprarrboolis normal FP32|64_IsNormal fprarrboolis sub-normal FP32|64_IsSubnormal fprarrboolis zero FP32|64_IsZero fprarrbool

27

comparison FP32|64_Compare fptimes fprarrieee_compareequality FP32|64_Equal fptimes fprarrboolless than FP32|64_LessThan fptimes fprarrboolless than or equal FP32|64_LessEqual fptimes fprarrboolgreater than FP32|64_GreaterThan fptimes fprarrboolgreater than or equal FP32|64_GreaterEqual fptimes fprarrbool

absolute FP32|64_Abs fprarrfpnegation FP32|64_Neg fprarrfpsquare root FP32|64_Sqrt ieee_roundingtimes fprarrfp(with flags) FP32|64_Sqrt_ ieee_roundingtimes fprarrieee_flagstimes fpaddition FP32|64_Add ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Add_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpsubtraction FP32|64_Sub ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Sub_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpmultiplication FP32|64_Mul ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Mul_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpfused multiply-add FP32|64_MulAdd ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulAdd_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpfused multiply-sub FP32|64_MulSub ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulSub_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpdivision FP32|64_Div ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Div_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fp

The L3 interpreter supports evaluation for 32-bit and 64-bit floating-point expressions but onlywhen running on an x86 machine that supports SSE2 extensions (Pentium 4 and later) Thefused multiply-addsub operations can only be interpreted on machines supporting the FMAextension which came in with the 4th generation (Haswell) Intel processors These restrictionsalso apply to any Standard ML code that is generated by L3

The IEEE 754 standard permits a number of different ways to flag underflow L3 predomi-nantly supports the x86 interpretation which detects underflow after rounding However whenexporting to HOL4 it is possible to choose detection before rounding which for example issuited to ARM instruction set models

A9 Miscellaneous operationsThe following operations are available

pair constructor αtimes β rarr αtimes βfirst of pair Fst αtimes β rarr αsecond of pair Snd αtimes β rarr β

casting [middot] α rarr βinitialise a map InitMap α rarr (βrarrα)

28

option constructor Some αrarrα optionoption projection ValOf α option rarr αoption test IsSome α option rarr bool

set membership in αtimesα set rarr boolset non-membership notin αtimesα set rarr boolset insertion insert αtimesα set rarrα setset union Union α settimesα set rarrα setset intersection Intersect α settimesα set rarrα setset difference Difference α settimesα set rarrα setset subset test IsSubset α settimesα set rarr boolset cardinality Cardinality α setrarr natset from a list SetOfList α list rarrα set

empty list Nil α listlist constructor Cons αtimesα list rarr α listlist head Head α list rarr αlist tail Tail α list rarr α listlist length Length α list rarr natlist concatenation α listtimesα list rarr α listlist flatten Concat α list list rarr α listlist element Element nattimesα list rarr αlist prefix Take nattimesα list rarr α listlist drop prefix Drop nattimesα list rarr α listlist pad left PadLeft αtimes nattimesα list rarr α listlist pad right PadRight αtimes nattimesα list rarr α listlist update Update αtimes nattimesα list rarr α listlist difference Remove α listtimesα list rarr α listlist intersection RemoveExcept α listtimesα list rarr α listlist without duplicates RemoveDuplicates α listrarr α listlist membership IsMember αtimesα list rarr boollist member position IndexOf αtimesα list rarr nat option

Sets are only defined over equality types see Appendix A2 The casting map is defined overcast-able types (as represented by the polymorphic type variables α and β) these are the primitivetypes (with the exception of lsquounitrsquo) and user defined enumerated types Assume lsquoEnumrsquo and lsquoEnum2rsquoare declared with

construct Enum One Two Three construct Enum2 Four Five Six Seven

The cast operations are described in Tables 1 to 7

29

Table 1 Cast to lsquoboolrsquo

From Operation Examples

bool identity lsquo[true]boolrsquo = lsquotruersquostring parse bool lsquo[true]boolrsquo = lsquotruersquo

lsquo[false]boolrsquo = lsquofalsersquootherwise undefined

nat is not zero lsquo[0n3]boolrsquo = lsquotruersquolsquo[0n0]boolrsquo = lsquofalsersquo

int is not zero lsquo[-0i1]boolrsquo = lsquotruersquolsquo[0i0]boolrsquo = lsquofalsersquo

bool list is not zero lsquo[0s11]boolrsquo = lsquotruersquolsquo[0s0]boolrsquo = lsquofalsersquo

bits(middot) is not zero lsquo[3`3]boolrsquo = lsquotruersquolsquo[0`3]boolrsquo = lsquofalsersquo

Enum is not the first element lsquo[One]boolrsquo = lsquofalsersquolsquo[Two]boolrsquo = lsquotruersquo

Table 2 Cast to lsquostringrsquo

From Operation Examples

bool name lsquo[true]stringrsquo = lsquotruersquostring identity lsquo[hello]stringrsquo = lsquohellorsquonat decimal lsquo[0n3]stringrsquo = lsquo3rsquoint signed decimal lsquo[-0i1]stringrsquo = lsquo~1rsquobool list binary lsquo[0s11]stringrsquo = lsquo11rsquobits(middot) unsigned hexadecimal lsquo[139`8]stringrsquo = lsquo8BrsquoEnum name lsquo[One]stringrsquo = lsquoOnersquo

30

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

14 Global StateGlobal variables are introduced using the lsquodeclarersquo construct which adds elements to the globalstate-space The following represent valid variable declarations

declare number natdeclare integer int boolean bool -- two declarationsdeclare pc bits(32) r1 bits(64) -- commas are optional

At the point of declaration it is not possible to specify initial values Users can specify (and latercall) their own initialisation procedures if required

The lsquolt-rsquo operator is used to assign values to mutable variables for example

pc lt- 0xF -- an assigment

assigns value lsquo0xFrsquo to our declared global variable lsquopcrsquo The bit-string and bit-vector types alsopermit assignment to bit-ranges for example

pclt30gt lt- 0xF pclt31gt lt- true -- a sequence of assigments

will set the bottom four bits and then the most-significant bit of lsquopcrsquo

15 TuplesTuples can be formed using the pairing constructor lsquorsquo which associates to the right Bracketingis optional (but recommended) for example all of the following expressions are semanticallyidentical

one true falseone (true false)(one true false) -- preferred form(one (true false))

These expressions have type lsquostring bool boolrsquo3 Note that the expression

((one true) false)

has type lsquo(string bool) boolrsquo which makes it strictly type distinct from (incompatiblewith) the previous expression

Note that (in expressions) commas are the loosest binding operator which means that

x y == 3 4

will parse as

(x ((y == 3) 4)) -- fully elaborated form

and not as

(x y) == (3 4) -- this could be what was intended

It is advisable that users only drop brackets when there is little chance of ambiguity3This is the same as lsquostring (bool bool)rsquo

3

16 MapsMaps are used to represent total functions4 For example the declaration

type map nat -gt int -- a map type pseudonym

introduces a type pseudonym for maps with domain lsquonatrsquo and codomain lsquointrsquo Maps and singlemap entries can be assigned to for example given the declaration

declare -- three global maps

m1 mapm2 mapm3 nat -gt nat

the statement m1 lt- m2 m1(1) lt- 2

will set map lsquom1rsquo to be lsquom2rsquo and this map is then updated so that lsquom1(1)rsquo takes value lsquo2rsquoThe language encourages the use of simple un-curried maps which means that the type

type map bool nat -gt int

should be used in preference totype nmap nat -gt inttype map bool -gt nmap

In particular the language does not permit the syntax lsquom(true)(2)rsquo whereas lsquom(true 2)rsquo is fineThe language does not provide a mechanism for specifying anonymous functions or anonymous

maps5 Furthermore maps and operations (either primitive or user defined) are considered to bedistinct As such it is not possible to make assignments of the form lsquom3 lt- Log2rsquo

17 Sum TypesEnumerated and sum (tagged union) types can be introduced using the lsquoconstructrsquo keywordFor example the declaration

construct enumerated Zero One Two Three -- a new type called enumerated

introduces a new type lsquoenumeratedrsquo that consists of four elements (new constants) Sum typescan be declared in a similar manner for example

construct bool_option BoolNone BoolSome bool -- an unnecessary variant of bool option

The elements of this new type are lsquoBoolNonersquo lsquoBoolSome(false)rsquo and lsquoBoolSome(true)rsquo6 Everyconstructor of the sum type must map from a pre-existing type (or be nullary) and this precludesthe definition of new recursive or mutually recursive datatypes

Enumerated types (where every constructor is nullary) admit casting tofrom numeric types7For example lsquo[One]natrsquo is equal to lsquo0n1rsquo and lsquo[0n1]enumeratedrsquo is equal to lsquoOnersquo

4Maps must have an equality type as their domain They can be viewed as a form of array and are typically usedto model memories and register banks

5The function lsquofn x =gt x + 1rsquo is an example of an anonymous function in Standard ML6The brackets are needed here for example lsquoBoolSome truersquo will not parse7The same does not hold for general sum types

4

18 RecordsRecord types can be introduced using the lsquorecordrsquo construct The following is an example of arecord declaration

record rec

number natinteger intboolean bool

Every value of type lsquorecrsquo has three components which may be accessed using dot notation forexample if we have a global variable

declare rec rec

then the sub-elements are lsquorecnumberrsquo lsquorecintegerrsquo and lsquorecbooleanrsquo The language does notprovide a syntax for record literals As such records must be built up incrementally for examplethe following is a sequence of assignments to components of the variable lsquorecrsquo

recnumber lt- 1 recinteger lt- 2 recboolean lt- true

It is not possible to express this with a single assignment to lsquorecrsquo

19 RegistersRegister types can be introduced using the lsquoregisterrsquo construct for example

register sreg bits(32)

31-28 FLAGS7-0 27-16 MODE15-12 MASK

This declares a new type lsquosregrsquo that represents the following 32-bit register31 28 27 16 15 12 11 8 7 0

FLAGS MODElt110gt MASK MODElt1912gt

Note that the bit-field 118 of lsquosregrsquo does not correspond with a named component Also notethat fields are allowed to be non-contiguous which is the case for the lsquoMODErsquo field Register typesare essentially special forms of record types with the automatic specification of bijections toa bit-vector representation Each named bit-field can be accessed using the dot notation forexample if we have

declare status sreg

then the fields lsquostatusFLAGSrsquo and lsquostatusMASKrsquo have type lsquobits(4)rsquo and lsquostatusMODErsquo has typelsquobits(20)rsquo Unlike records register types automatic admit casting tofrom an underlying bit-vector type The expression lsquoampstatusrsquo gives the value of the register (with type lsquobits(32)rsquo) andlsquosreg(0xFFFF0000)rsquo constructs a register of type lsquosregrsquo It is possible to use this notation to updatearbitrary bit-fields of a register for example the statement

ampstatuslt207gt lt- 11101101100111

will update the bit-field 207 of lsquostatusrsquo using the 14-bit literal value

5

110 Polymorphic TypesUsers cannot declare their own polymorphic types Furthermore all user defined operations andvariables must be monomorphic The language does however provide support for three built-inpolymorphic datatypes which may be used under the proviso that these types are always fullytype instantiated (free of type variables)

1101 ListsThe language provides limited support for working with lists Lists can be specified as follows

list 0n0 2 4 -- a list of naturals (length three)0n0 2 3 Nil -- expanded versionCons (0n0 Cons (2 Cons (4 Nil))) -- equivalent version

These expressions have type lsquonat listrsquo Given the first-order nature of L3 only simple listoperations are provided (for example lsquoHeadrsquo lsquoTailrsquo and lsquoLengthrsquo) Higher-order list operationssuch as filter map and fold are not available

1102 Finite SetsThe language provides basic support for finite sets Sets can be specified as follows

set 0n0 2 4 -- a three element set (of naturals)0n0 insert 2 insert 4 insert set -- an expanded versionSetOfList (list 0n0 2 4 ) -- a version built from a list

These expressions have type lsquonat setrsquo The infix operators lsquoinrsquo and lsquonotinrsquo test for set member-ship for example the expressions

0n0 in set 0 2 4 -- test for membership0n1 notin set 0 2 4 -- test for non-membership

both evaluate to lsquotruersquo Sets can only be defined over equality types It is not possible forexample to construct the type lsquo(bool -gt bool) setrsquo

1103 Option TypesThe option type is a polymorphic sum type that has two constructors lsquoNoneα optionrsquo andlsquoSomeαrarrα optionrsquo Option types are helpful when specifying partial operations

111 Statements and ExpressionsThis section presents the statements and expressions of the language Statements can be groupedinto blocks using the syntax

statement1 -- do thisstatement2 -- then do thismiddot middot middot

6

Each block and sub-statement has type lsquounitrsquo The operator lsquorsquo is strictly binary trailing semi-colons not permitted at the end of a sequence of statements Expressions are distinct fromstatements in particular expressions preclude assignments

1111 NothingThe statement lsquonothingrsquo has no effect Its primary purpose is to facilitate the specification ofcontrol flows wherein some paths do something (update the state) and others do nothing8

1112 ConditionalsThe language supports if-then-else statements and expressions and when-do statements Thelatter is provided as a convenient shorthand that is to say the statement

when p do x

is equivalent to the statement

if p then x else nothing

Note that the language does not support layout syntax (the off-side-rule)

1113 For LoopsThe language provides support for simple for-loop statements On each iteration of a for-loopa natural number index variable is either incremented or decremented (by one) This process isrepeated until the index value reaches a pre-computed upper or lower bound for example theloop statements

for i in 1 3 do proc(i)for i in 3 1 do proc(i)

are respectively equivalent to

proc(1) proc(2) proc(3) proc(3) proc(2) proc(1)

The initial and final loop index values may be arbitrary natural number expressions As suchit may be the case that the loop direction will only be known once these bound expressions arecomputed

In addition to regular for loops the language also supports foreach loops which operate overlists For example the following code makes three calls to lsquoprocrsquo

foreach i in list 0n2 4 6 do proc(i)

Note that this construct will also work for bit-strings and for normal stringsThere is no support for do while or repeat until loops

8The lsquonothingrsquo statement is essentially syntactic sugar for lsquo()rsquo

7

1114 Exceptions Unknown and UndefinedThe keyword lsquoUNKNOWNrsquo is used to represent an unspecified element which may be of any giventype The language does not stipulate whether or not this value should be chosen deterministi-cally If the value were chosen deterministically then the expression lsquoUNKNOWN == UNKNOWNrsquo willalways be lsquotruersquo However if the choice is non-deterministic then there is no way of knowing ifan occurrence of this expression is lsquotruersquo or lsquofalsersquo

The language supports user defined exceptions which may be raised but not caught Thelsquoexceptionrsquo keyword is used to declare new exception categories for example

exception ASSERT string

introduces a new exception lsquoASSERTrsquo that takes a single string as an argument This exception canbe raised in expressions and statements as follows

ASSERT (an error has occurred)

Thus exceptions can be used to flag the occurrence of a variety of different errors The L3interpreter will stop when an exception is raised Exceptions can be raised within expressionsand are not constrained by return type

The behaviour of various operations is undefined on some inputs for example the arithmeticexpression lsquox div 0n0rsquo is undefined For any given undefined expression the language permitsthree possible interpretations (implementations)

bull A deterministic value can be chosen For example lsquox div 0n0rsquo is equal to lsquo0n0rsquo is a validinterpretation of this undefined expression

bull A non-deterministic value can be chosen In particular is not necessary for the expressionlsquox div 0n0 == x div 0n0rsquo to be lsquotruersquo

bull An exception can be raised

It is expected that specifications will be designed with some preferred treatment of undefinedbehaviour in mind In this example one possible way to manage undefined cases is by takingcare to explicitly write code of the form lsquoif n == 0 then else x div n rsquo This willensure that undefined cases are unreachable

1115 Procedure CallsA procedure is any user defined operation with return type lsquounitrsquo Procedures typically providefunctionality by means of updating the global state (through side effects) Procedures can becalled (and exceptions can be raised) in statement blocks for example

middot middot middotproc (1 true) -- this is a procedure callmiddot middot middot

The following code is valid but not recommended

8

middot middot middotASSERT error -- raise an exceptionproc (1 true) -- the L3 interpreter will never reach this code

In the above the exception is unconditionally raised so the remaining code should be regardedas unreachable (redundant)

1116 Local VariablesThe L3 language supports two varieties of variables mutable and immutable All global vari-ables are mutable The keyword lsquovarrsquo is used to declare new mutable variables with local scopeLocal variables can be introduced anywhere within a statement block and these variables canbe assigned to using the lsquolt-rsquo operator Immutable variables are introduced within a block usingthe syntax lsquox = expr rsquo and this is treated as a let-statement An immutable value cannot beupdated however it can fall out of scope by declaring a new immutable variable with the samename The operators lsquolt-rsquo and lsquo=rsquo are not permitted in expressions

The specification below uses two mutable variables lsquoxrsquo and lsquoyrsquo

var y = zvar x = yif p then xlt30gt lt- 1111 y lt- x + 1

else xlt74gt lt- 1111 y lt- 0 return (x + y)

This could be respecified using immutable variables for example

y = zx = yx y = if p then (x || 00001111 x || 00001111 + 1)

else (x || 11110000 0)return (x + y)

It is not always easy to eliminate mutable variables In this case the second specification ismore cumbersome because the bit-field update has been replace by an explicit mask (bitwise-or)operation This operations has been repeated in specify the value of lsquoyrsquo because assignments arenot permitted in expressions

Mutable variables can be declared without an initial assignment for example lsquovar xrsquo isequivalent to lsquovar x = UNKNOWNrsquo

1117 PatternMatchingThe language supports match statements and expressions Pattern matching is supported withrespect to literals (see Section 13) constructors9 (immutable) variables wildcards (anonymousvariables) and bit-patterns

9This includes matching on tuples as well as lsquoNonersquo lsquoSomersquo lsquoConsrsquo and lsquoNilrsquo Matching on finite sets and recordfields is not possible

9

Given the type declarations

construct enum One Two Three construct data

NoDataData1 string bits(8)Data2 enum bits(16)

the following illustrates a match expression

match y

case -1 NoData or -2 NoData =gt 0`4 -- note use of orcase _ Data1 (hello 11 x 11) =gt x + 1 -- use of bit-patterncase i Data2 (Three 1111 y) =gt [i] + ylt30gtcase 1 Data2 (_ 8) =gt 4case _ =gt 8

The body (right-hand side of lsquo=gtrsquo) of the first case line with a matching pattern is selected Thesymbol lsquo_rsquo is a wildcard and will match any value The lsquoorrsquo construct provides a shorthand forwriting blocks of clauses with differing patterns but the same body

The terms lsquo11 x 11rsquo and lsquo1111 yrsquo are called bit-patterns and they will match against a setof bit-vector values From the type declaration of lsquodatarsquo it is known that the variable lsquoxrsquo mustrepresent a 4-bit value because it occurs in the middle of an 8-bit word (the match requires bitslsquo11rsquo as a prefix and as a suffix) Likewise lsquoyrsquo must be a 12-bit value Multiple variables can occurin a bit-patterns for example lsquo1 x 1 y 0rsquo is a valid bit-pattern The type checker will oftenbe able to infer the type of pattern variables and if this fails type annotations can be added

The lsquopatternrsquo construct can help avoid situations where explicit annotations are repeatedlyrequired (causing clutter in patterns) If for example the variable lsquoimm5rsquo is frequently used tomatch a 5-bit value then the following declaration can be made

pattern imm5 bits(5)

In subsequent code the default type for pattern variable lsquoimm5rsquo will be lsquobits(5)rsquo The lsquopatternrsquoconstruct only influences type checking If a particular type hint is no longer appropriate thenit can be dropped for example one can insert the declaration lsquoclear pattern imm5rsquo

112 Defining Constants and OperationsUsers can construct operational semantics style formal specifications in L3 by defining their ownconstants and operations There is no module system or facility for local definitions all userdefinitions are made at the top-level with global scope User constants and operations cannot beoverloaded or redefined

A pure constant is a nullary (zero argument) operation that is state independent for examplethe following code declares a new constant

bits(32) UINT_MAX = 0xFFFFFFFF

10

The following code declares operations that are nullary but state dependent

declare number Natnat numberPlus1 = return (number + 1)unit incNumber = number lt- numberPlus1

Users can also declare new unary operations which may or may not be state dependent forexample

nat numberMinusN (nnat) = return (number + n) -- state dependentunit decNumber () = number lt- numberMinusN (1)nat mla (mnatnnatanat) = return (m n + a) -- pure

The operation lsquomlarsquo is unary because it takes a single triple as an argument To enhance clarityand avoid misunderstandards users may elect to specify nullary state dependent operations usinga single lsquounitrsquo argument Given the declarations above the expression lsquodecNumber()rsquo gives theclear impression that a call is being made (with possible side-effects) wheres the expressionlsquoincNumberrsquo does not

At the point of declaration operation arguments must be fully type annotated and onlymonomorphic types are allowed10 It is nevertheless possible to declare bit-vector operationsthat are valid with respect to some given set of bit widths for example the following are validdeclarations

--- valid for any bit-vector width N ---bits(N) bv_mla (mbits(N) nbits(N) abits(N)) = return (m n + a)

--- valid for sufficiently wide bit-vectors (N greater than eight) ---bool bit8 (xbits(N)) with N gt 8 = return (xlt8gt)

An L3 type error will arise if ever an application of the operation lsquobit8rsquo violates the bit widthconstraint Note that vector width variables (such as lsquoNnatrsquo above) can be used as if they werea regular variables in the definitional body of an operation

113 ComponentsWhen specifying instruction set architectures the two most significant programmerrsquos modelcomponents are typically the main memory and a collection of general purpose registers In theMIPS architecture for example there are thirty-two general purpose registers which may berepresented using the following map

declare gpr bits(5) -gt bits(64)

The statement

gpr(d) lt- gpr(r)10An compile time error will arise if the type checker is not able to infer all types the final definition must be

free of type variables

11

then expresses moving a value from register lsquorrsquo to register lsquodrsquo However register a memory accessis frequently more complicated than this in particular registers can be banked and memory canbe complex11 As such it is often necessary to specify collections of operations for accessing(reading and writing) these components With the MIPS example register zero is special (it isa constant value) and so one could define the following operations

bits(64) read_gpr (nbits(5)) = if n == 0 then 0 else gpr (n)unit write_gpr (vbits(64) nbits(5)) = when n ltgt 0 do gpr (n) lt- v

Thus the previous register transfers would now be specified as follows

write_gpr (read_gpr (n) d)

This precise style of specification is not entirely satisfying though since it departs in appearancefrom the pseudo code found in MIPS reference manuals The L3 language provides a specialmechanism for specifying a pair of operations that read and write state components With theMIPS example the following declaration can be made

component GPR (nbits(5)) bits(64)

value = if n == 0 then 0 else gpr(n)assign value = when n ltgt 0 do gpr(n) lt- value

One can then write

GPR(d) lt- GPR(r)

which is closer to the syntax used in the MIPS reference manuals The lsquocomponentrsquo constructeffectively provides a controlled form of operator overloading whereby the lsquoassignrsquo operation12

is select when the operator name appears on the left-hand side of an assignment (lsquolt-rsquo) and thelsquovaluersquo operation13 is applied otherwise Semantically these two operations are exactly the sameas the manually defined versions lsquowrite_gprrsquo and lsquoread_gprrsquo The ldquowriterdquo operation will alwayshave a lsquounitrsquo return type Users are free to specify the ldquoreadrdquo and ldquowriterdquo operations in any mannerthat they deem appropriate however the ldquowriterdquo operation cannot be defined recursively norcan the ldquoreadrdquo operation call the ldquowriterdquo operation

114 RecursionThe language permits the definition of recursive operations It is not possible to define mutuallyrecursive operations

The L3 language has been designed to act as an authoring front-end for the HOL4 theoremprover facilitating the task of writing instruction set specifications In order to successfullyimport an L3 specification it is necessary for the HOL4 system to prove that every user defined

11ARM registers are banked according to processor mode Memory can often be accessed with big- and little-endian byte ordering Special treatment may be needed for unaligned memory addresses for example when readinga 16-bit value from an odd address There may also be address translation (virtualisation) and memory hierarchies(caching)

12In this example the ldquowriterdquo operations is internally called lsquowriteGPRrsquo13Internally the ldquoreadrdquo operation is simply called lsquoGPRrsquo

12

operation is total (terminates on all inputs) If an L3 function is non-terminating then it willbe impossible to export that definition to HOL4 If a function is terminating but the standardautomation of HOL4 is unable to construct a termination proof then it may be necessary toprovide the prover with a hint in the form of a measure

Consider the following specification

declare m bits(8) -gt bits(8)

unit load (abits(8) lbits(8) list) =match l

case Nil =gt nothingcase Cons (h t) =gt m(a) lt- h load (a + 1 t)

The lsquoloadrsquo operation recurses over the list lsquolrsquo loading values into the map lsquomrsquo At the time ofwriting this documentation trying to build the exported HOL4 version of this specificationgives rise to the following error message

Initial goal

existRWF R andforallstate a l h t

(l = ht) rArrR ((a + 1wt)state with m = (a =+ h) statem) ((al)state)

Exception raised at TotalDefnDefinebetween beginning of frag 0 and end of frag 0at TotalDefndefnDefine

Unable to prove termination

Try using TotalDefntDefine ltnamegt ltquotationgt lttacgt

This occurs because HOL4 is unable to automatically prove that lsquoloadrsquo always terminates Toget around this problem the original L3 specification can be modified to contain an annotationas follows

unit load (abits(8) lbits(8) list) measure Length(l) =

The metadata lsquomeasure Length(l)rsquo tells HOL4 to examine the length of the list lsquolrsquo since thisvalue will decrease upon each recursive call to lsquoloadrsquo When the length of the list is zero (thelsquoNilrsquo case) there are no recursive calls so termination is guaranteed

The expression occurring after the lsquomeasurersquo keyword must be of type lsquonatrsquo After provid-ing a measure it is still possible that HOL4 will fail to prove termination either because thesupplied measure is incorrect or because the termination proof is non-trivial (requires humanguidance andor custom lemmas) If this occurs then users should either simplifyrewrite theirspecifications or if necessary report the problem

13

115 Instruction Set DefinitionsWhen working with instruction set models it is helpful to construct a datatype that representsthe set of machine (low-level) instructions This datatype constitutes a simple form of abstractsyntax tree (AST) and it can be used to build instruction decoders (identifying machine-codeinstructions and splitting opcodes into sub-fields) instruction encoders (generating opcodes fora given instruction) next-state functions (applying a semantics function for a given instruction)and assembly code parsers

By way of an example consider the MIPS instruction ANDI this instruction has the assemblycode syntax

ANDI rt rs immediate

and the following 32-bit machine-code encoding

31 26 25 21 20 16 15 0

001100 rs rt immediate6 5 5 16

The semantics of this instruction can be expressed with the operation

unit run_ANDI (rsbits(5) rtbits(5) immbits(16)) =GPR(rt) lt- GPR(rs) ampamp ZeroExtend (imm)

One could use this operation to directly specify a next-state function which would be of theform

unit Next =match Fetch -- fetches a 32-bit opcode from memory

middot middot middotcase 001100 rs rt imm =gt run_ANDI (rs rt imm)middot middot middot

This style of specification is direct and concise however it does lack some of the flexibility thatcomes with using an instruction datatype The L3 language provides support for an slightlydifferent style of specification This alternative approach is explained by first examining howone would specify things manually (explicitly) and then showing how L3 can streamline thisprocess

Firstly one could explicitly define an AST datatype for MIPS instructions it would be ofthe form

construct instruction

middot middot middotANDI bits(5) bits(5) bits(16)middot middot middot

14

This datatype provides a suitable constructor for the ANDI instruction It is now possible to definea decoder which maps opcodes onto AST entries for example

instruction Decode (opcbits(32)) =match opc

middot middot middotcase 001100 rs rt imm =gt ANDI (rs rt imm)middot middot middot

This decoder can be used to define our next-state function that is

unit Next = Run (Decode (Fetch))

where lsquoRunrsquo is defined by

unit Run (iinstruction) =match i

middot middot middotcase ANDI (args) =gt run_ANDI (args)middot middot middot

When working with full-scale architecture specifications (where the AST type is large) thereare some clear overheads associated with implementing this approach (in comparison with theAST free version) It becomes challenging to maintain the AST datatype declaration and tokeep it correctly synchronised with the instruction semantics operations (such as lsquorun_ANDIrsquo)and the definition of lsquoRunrsquo Note however that there is great uniformity in the AST datatypedeclaration and also in the definition of lsquoRunrsquo As such L3 is able to automatically define bothof these for the user

To make use of this automation the declaration of lsquorun_ANDIrsquo is simply modified to

define ANDI (rsbits(5) rtbits(5) immbits(16)) =GPR(rt) lt- GPR(rs) ampamp ZeroExtend (imm)

The lsquodefinersquo keyword tells L3 to define a semantics function14 (as before) and to also create anew lsquoinstructionrsquo datatype AST entry furthermore the two will be linked with the automaticconstruction of a lsquoRunrsquo function The lsquoinstructionrsquo type and lsquoRunrsquo function become defined (inscope) following the declaration lsquodefine Runrsquo After this declaration it is no longer possible touse the lsquodefinersquo construct again however it does become possible to define functions such aslsquoDecodersquo and lsquoNextrsquo

Specifications that are based on using lsquodefinersquo gain the benefits of declaring an instructionAST datatype without the downside of laborious coding overheads In the example above theoverhead amounts to one extra line of code this comes from defining a next-state function thatcalls the dedicated decode function followed by a call to lsquoRunrsquo

One of the key advantages of declaring an instruction datatype is that it makes it consider-ably easier to develop tools that work with assembly code syntax (performing parsing encoding

14This function is internally called lsquodfnANDIrsquo instead of lsquorun_ANDIrsquo

15

and pretty-printing) In this case it is relatively easy for example to map between the MIPSinstruction syntax andi $5 $6 1024 and the expression lsquoANDI (5 6 1024)rsquo Defining anencoder in L3 is relatively straightforward for example

bits(32) Encode (iinstruction) =match i

middot middot middotcase ANDI (rs rt imm) =gt 001100 rs rt immmiddot middot middot

Such a function can be used to write a MIPS assembler which would map the assembly codesyntax andi $5 $6 1024 onto the machine-code value 0x30c50400

2 TutorialThis section gives a brief overview of how to install and use L3

Installation The sources for L3 can be downloaded from the following webpage

wwwclcamacuk~acjf3l3

The file l3tarbz2 can be unpacked with the command

$ tar xvjf l3tarbz2

This will create a directory of the form L3-YYYY-MM-DD where the year month and day willcorrespond with the release date The current version of L3 depends upon PolyML 57 whichcan be obtained from the site polymlorg If PolyML is installed then L3 can be built as follows

$ cd L3-YYYY-MM-DD$ make

Once built the following should appear when you start L315

$ l3ltlt L3 gtgtgt

Users should consider running L3 with the command rlwrap l316

15This assumes that the directory L3-YYYY-MM-DDbin has been added to the PATH environment variable16Details on rlwrap utility can be found at the site freecodecomprojectsrlwrap

16

Basic Interaction The command prompt for L3 is essentially the read-eval-print loop (REPL)of PolyML As such users are free to write arbitrary Standard ML code The structure Runtimeenables interaction with L3 The following shows an arithmetic evaluation in Standard ML aswell as in the L3 interpreter (evalQ)

gt 1 + 2val it = 3 intgt RuntimeevalQ `0i1 + 2`val it = `0i3` Termterm

Various error messages can occur when using the interpreter for example

gt RuntimeevalQ `1 + 2`Exception- Fail Could not infer all types raised

gt RuntimeevalQ `0i2 div 0`Exception- Except (Div SOME (div (int [`0i2` `0i0`]))) raised

The first error occurs because unannotated number literals are regarded as bit-vector values andhere the vector width cannot be inferred

L3 declarations can be made using the function loadQ The following sequence shows thedeclaration and manipulation of a global variable

gt RuntimeloadQ `declare n nat`ltVARgt nval it = () unit

gt RuntimeevalQ `n`val it = `UNKNOWNnat` Termterm

gt RuntimeevalQ ` n lt- 3 n `val it = `0n3` Termterm

The global state can be examined using the function show for example

gt Runtimeshow()val it = [(n `0n3`)] Evalterm_stack

The state can be ldquowipedrdquo clean using the function reset and all declarations can be wiped usinglsquoresetAllrsquo for example

gt Runtimereset()val it = () unitgt Runtimeshow()val it = [(n `UNKNOWNnat`)] Evalterm_stack

gt RuntimeresetAll()val it = () unitgt Runtimeshow()val it = [] Evalterm_stack

The function lsquoLoadQrsquo is similar to lsquoloadQrsquo but it performs a lsquoresetAllrsquo before making declarations

17

Constants The structure Consts provides various functions for working with L3 constantsMany of the operation in the Consts structure will be of little interest to end-users however itcan be used to display some helpful information

The function ConstslookupConst can be used to lookup an operation for example

gt ConstslookupConst Log2val it = Primitive [(bits(a) -gt bits(a) -) (nat -gt nat -)] const

Since lsquoLog2rsquo is a primitive operation only the valid types (ordered by overload priority) are showWith user operations the internal representation (definition) of the operation will be shownfor example

gt RuntimeLoadQ `unit demo () = ()`gt ConstslookupConst demoval it = Definition (Abs ([(_ (unit -))] unit -gt unit `()`) NONE 1)

Constsconst

The functions ConstslistDefinitions and ConstslistExceptions provide details of all useroperations and exceptions respectively The function lsquoConstsstatsrsquo gives a summary of all thecurrent declarations

gt Constsstats()Primitives 188Destructors 5Constructors 0Accessors 0Exceptions 0User operations 1Instruction definitions 0

Here the constructors for primitive types (such as lsquoConsrsquo) are counted under ldquoprimitivesrdquo

Types The Types structure can be used to display information relating to L3 types In partic-ular this structure provides the functions TypeslookupConst and TypeslistConsts which aredemonstrated below

gt RuntimeloadQ `construct enum One Two Three`gt TypeslistConsts()val it =

[(enumeq = true ast = false def = Constructors (Enum ltdict(3)gt) num = 0)]

(string typeconst) list

gt TypeslookupConst intval it = SOME eq = true ast = false def = BaseType num = ~1

typeconst option

18

Loading and Exporting Specifications When writing an L3 specification it is expected thatuser declarations will be contained in an L3 source file A sample instruction set specification(tinyspec) can be found in the L3 distribution subdirectory examples This specification isbased on Thackerrsquos pedagogical Tiny 3 architecture it can be loaded as follows

gt RuntimeLoadF tinyspecLoading tinyspecltTYPgt regTltTYPgt wordTmiddot middot middotltFUNgt test_progDone

The string argument to the functions RuntimeloadF and RuntimeLoadF can be in the form ofa comma separated list of files which will be loaded in order That is the call

RuntimeloadF aspec bspec

will load aspec followed by bspecThe function HolExportexport will export the current L3 specification in the form of an

HOL4 script for example

gt HolExportexport tinyraiseexception okfunction okmiddot middot middotmextend skipmunextend skipCreated file tinyScriptsmlCreated file tinyLibsmlCreated file tinyLibsigDone

The function HolExportspec provides a convenient shortcut for performing LoadF and exportusing just a single call for example HolExportspec (tinyspec tiny) will perform theload and export presented above

L3 is capable of exporting two styles of HOL specification an explicitly monadic version(based on state_transformerTheory) and a version that directly manipulates state using let-expressions (which is the default style) For example a monadic version of the Tiny specifi-cation can be exported using the command HolExportspec (tinyspec tiny monadic)Other export options include sigdocs nosigdocs (for setting HOLrsquos TheoryPPinclude_docstrace variable) bigrecords nobigrecords (for controlling HOLrsquos Datatypebig_record_size)and underflowbefore nounderflowbefore (for selecting the required IEEE 754 underflow be-haviour)

Generated HOL4 specifications are not designed to be manually edited (or human readable)To build an L3 specification script the HOL library Import is needed This library is currentlylocated in the directory $HOL_DIRexamplesl3-machine-codecommon and so adding this path tothe INCLUDES variable of a local Holmakefile is recommended The examplesl3-machine-codedirectory contains various examples of using L3 generated specifications

19

Testing Specifications Having written an L3 specification it is fairly easy to write code (inStandard ML) that runs test vectors Code for running the tinyspec example can be found inthe file run-tinyspec In this test harness the Tiny state is initialised and a small test programis loaded simply by evaluating the expression lsquoinitialize (test_prog)rsquo

It is also possible to evaluate (run) models that have been exported to HOL4 The filerun-tinysml shows how this can be accomplished for the Tiny example

20

A Primitive Types and OperationsThe primitive types are as follows

unit bool char nat int bits(middot) rounding

There are two infix type constructors lsquorsquo for pairs and lsquo-gtrsquo for maps There are also postfix typeconstructors lsquosetrsquo lsquooptionrsquo and lsquolistrsquo for example sets of strings are represented by the typelsquostring setrsquo The following sections describe these primitive types together with some detailsof associated operations The following constants and operations are available

nullary () Nil None false roundTiesToEven roundTowardNegativeroundTowardPositive roundTowardZero true

prefix - ~ Abs Cardinality Cons Difference Drop Element FP32_AbsFP32_Add FP32_Equal FP32_IsNan FP32_LessThan FP32_MulFP32_Neg FP32_Sub FP64_Abs FP64_Add FP64_Equal FP64_IsNanFP64_LessThan FP64_Mul FP64_Neg FP64_Sub FromBinStringFromDecString FromHexString Fst Head IndexOf InitMapIntersection IsAlpha IsAlphaNum IsDigit IsHexDigit IsLowerIsMember IsSome IsSubset IsUpper Length Log2 Max Min MsbQuotRem Remove RemoveDuplicates RemoveExcept ReverseSetOfList SignExtend SignedMax SignedMin Size Snd Some TailTake ToLower ToUpper Union Update ValOf ZeroExtend not

infix = ampamp + - lt lt+ lt= lt=+ ltgt == gt gt+ gt= gt=+ ^ || gtgtltlt gtgt+ ltlt gtgt and div in insert mod notin or quot rem

sdivsmodother middot ltmiddotgt middot ltmiddotmiddotgt [middot] fields splitl splitr tokens

Many arithmetic operations are overloaded Unless otherwise stated the order of selection islsquobits(middot)rsquo lsquonatrsquo lsquointrsquo and then lsquobool listrsquo

A1 UnitThe type lsquounitrsquo represents the singleton set containing the value lsquo()rsquo The primary use of thistype is as the return type for procedures

A2 BoolThe type lsquoboolrsquo represents the two element set B = lsquotruersquo lsquofalsersquo The following standardBoolean operations are available

negation not bool rarr boolconjunction and booltimes bool rarr booldisjunction or booltimes bool rarr boolequality == αtimesα rarr boolnon-equality ltgt = αtimesα rarr bool

21

The infix operators lsquoandrsquo and lsquoorrsquo are interpreted with short-circuit evaluation for example in theexpression lsquofalse and f()rsquo the value of lsquof()rsquo is not computed as the overall expression will alwaysevaluate to false This short-circuiting influences the side-effects that occur during expressionevaluation

There are two prefix symbols for logical negation (these are semantically identical) with lsquorsquobinding slightly tighter than lsquonotrsquo This distinction is becomes significant when working withequalities for example lsquonot a == brsquo is taken to be not(a = b) whereas lsquoa == brsquo is (nota) = b

Equality is only defined with respect to equality types represented here by the type variableα An equality type is any type built without the used of the map operator lsquo-gtrsquo

A3 NatThe type lsquonatrsquo represents the natural numbers N = 0 1 2 The following operations areavailable

logarithm (base two) Log2 nat rarr natminimum value Min nattimes nat rarr natmaximium value Max nattimes nat rarr natless than lt nattimes nat rarr boolgreater than gt nattimes nat rarr boolless than or equal to lt= nattimes nat rarr boolgreater than or equal to gt= nattimes nat rarr booladdition + nattimes nat rarr natsubtraction - nattimes nat rarr natmultiplication nattimes nat rarr natexponentiation nattimes nat rarr natdivision div nattimes nat rarr natmodulus mod nattimes nat rarr nat

The lsquodivrsquo and lsquomodrsquo operations satisfy the following property

foralln 0 lt n =rArr forallk k = (k div n) lowast n+ (k mod n) and (k mod n) lt n

The expressions lsquoLog2(0)rsquo lsquox div 0rsquo and lsquox mod 0rsquo are all undefined 17

A4 IntThe type lsquointrsquo represents the integers Z = Ncupminus1minus2minus3 The following operations areavailable

17The interpreter will raise an exception when attempting to evaluate them

22

unary minus - int rarr intabsolute value Abs int rarr intminimum value Min inttimes int rarr intmaximum value Max inttimes int rarr intless than lt inttimes int rarr boolgreater than gt inttimes int rarr boolless than or equal to lt= inttimes int rarr boolgreater than or equal to gt= inttimes int rarr booladdition + inttimes int rarr intsubtraction - inttimes int rarr intmultiplication inttimes int rarr intexponentiation inttimes nat rarr intquotient and remainder QuotRem inttimes int rarr inttimes intquotient quot inttimes int rarr intremainder rem inttimes int rarr intdivision div inttimes int rarr intmodulus mod inttimes int rarr int

The operation lsquoAbsrsquo gives an positive integer value for example lsquoAbs(-2)rsquo = lsquo2rsquo The integeroperations lsquoquotrsquo and lsquodivrsquo are related to natural number division as follows

i quot j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

and

i div j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(minusi) div n(j))minus 1 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i and n(i) mod n(minusj) = 0

minus z(n(i) div n(minusj))minus 1 j lt 0 and 0 le i and n(i) mod n(minusj) = 0

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

where z NrarrZ and n ZrarrN are value preserving maps The lsquoremrsquo and lsquomodrsquo operations satisfythe equations

i rem j =

iminus (i quot j) lowast j j = 0

undefined j = 0i mod j =

iminus (i div j) lowast j j = 0

undefined j = 0

A5 Bit-vectorsThe type lsquobits(n)rsquo represents fixed-width (n-bit) words also known as bit-vectors for examplebits(32) is the type of 32-bit machine words18 The bits type can be viewed as representing

18These are called double-words (dword) in the x86 architecture and simply words in the ARM architecture

23

the set Zn = 0 1 2nminus1 for some 0 lt n At the type system level no distinction is madebetween signed and unsigned words however some operations (such as orderings) have signedand unsigned variants

The following bit-vector operations are available

1rsquos complement ~ bits(n) rarr bits(n)2rsquos complement - bits(n) rarr bits(n)absolute value Abs bits(n) rarr bits(n)logarithm (base two) Log2 bits(n) rarr bits(n)zero-extend ZeroExtend bits(m) rarr bits(n)sign-extend SignExtend bits(m) rarr bits(n)reverse bits Reverse bits(n) rarr bits(n)minimum value (u) Min bits(n)times bits(n) rarr bits(n)maximum value (u) Max bits(n)times bits(n) rarr bits(n)minimum value (s) SignedMin bits(n)times bits(n) rarr bits(n)maximum value (s) SignedMax bits(n)times bits(n) rarr bits(n)widthsize Size bits(n) rarr natmost-significant (sign) bit Msb bits(n) rarr boolbit value middot ltmiddotgt bits(n)times nat rarr boolbit field middot ltmiddotmiddotgt bits(m)times nattimes nat rarr bits(n)concatenation bits(m)times bits(n) rarr bits(p)duplication ^ bits(m)times nat rarr bits(n)less than (s) lt bits(n)times bits(n) rarr boolgreater than (s) gt bits(n)times bits(n) rarr boolless than or equal to (s) lt= bits(n)times bits(n) rarr boolgreater than or equal to (s) gt= bits(n)times bits(n) rarr boolless than (u) lt+ bits(n)times bits(n) rarr boolgreater than (u) gt+ bits(n)times bits(n) rarr boolless than or equal to (u) lt=+ bits(n)times bits(n) rarr boolgreater than or equal to (u) gt=+ bits(n)times bits(n) rarr booladdition + bits(n)times bits(n) rarr bits(n)subtraction - bits(n)times bits(n) rarr bits(n)multiplication bits(n)times bits(n) rarr bits(n)quotient (s) quot bits(n)times bits(n) rarr bits(n)remained (s) rem bits(n)times bits(n) rarr bits(n)division (u) div bits(n)times bits(n) rarr bits(n)modulus (u) mod bits(n)times bits(n) rarr bits(n)division (s) sdiv bits(n)times bits(n) rarr bits(n)modulus (s) smod bits(n)times bits(n) rarr bits(n)bitwise conjunction ampamp bits(n)times bits(n) rarr bits(n)bitwise disjunction || bits(n)times bits(n) rarr bits(n)bitwise exclusive-or bits(n)times bits(n) rarr bits(n)

Unsigned operations are labelled with (u) and signed operations are labelled with (s)The shift operations support shifting by either a bit-vector value or by a natural number value

The overloading is resolved such that the lsquonatrsquo variant is selected over the lsquobits(middot)rsquo version Theshift operations are

24

left-shift ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (u) gtgt+ bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (s) gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate left ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate right gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

A number of operations are undefined depending on the types of their domain and rangeThis is detailed in the following table

Operation Undefined when

ZeroExtend(x`n)`m m lt nSignExtend(x`n)`m m lt n(x`m)ltpgt m le p(x`m)lthlgt`n n = h+ 1minus l or h lt l orm le h((xm) (yn))`p p = m+ n((x`m) ^ n)`p p = m middot n (which covers n = 0)

The type checker will fail when these conditions are obviously violated Alternatively the inter-preter may raise a runtime error when these conditions are not met

As before the expressions lsquoLog2(0)rsquo lsquox quot 0rsquo lsquox rem 0rsquo lsquox div 0rsquo and lsquox mod 0rsquo are allundefined

A6 Bit-stringsVarious bit-string operation are defined over the type lsquobool listrsquo These are listed below

bit value middot ltmiddotgt bool listtimes nat rarr boolbit field middot ltmiddotmiddotgt bool listtimes nattimes nat rarr bool listconcatenation bool listtimes bool list rarr bool listduplication ^ bool listtimes nat rarr bool listaddition + bool listtimes bool list rarr bool listbitwise conjunction ampamp bool listtimes bool list rarr bool listbitwise disjunction || bool listtimes bool list rarr bool listbitwise exclusive-or bool listtimes bool list rarr bool listleft-shift ltlt bool listtimes nat rarr bool listright-shift gtgt+ bool listtimes nat rarr bool listrotate-right gtgt bool listtimes nat rarr bool list

The bit value operation gives the truth value of a bit-string at a given bit position for example

lsquo0s1101lt0gtrsquo = lsquotruersquo lsquo0s1101lt1gtrsquo = lsquofalsersquo lsquo0s1101lt2gtrsquo = lsquotruersquolsquo0s1101lt3gtrsquo = lsquotruersquo lsquo0s1101lt4gtrsquo = lsquofalsersquo lsquo0s1101lt5gtrsquo = lsquofalsersquo

25

The least-significant bit (position zero) occurs to the right of the bit-string The bit value oper-ation gives lsquofalsersquo when the bit position is greater than the size of the bit-string

The bit field operation extracts a range of bits from a bit-string For example

lsquo0s1101lt31gtrsquo = lsquo0s110rsquo and lsquo0s1101lt52gtrsquo = lsquo0s0011rsquo

In the bit-string expression xlthlgt the size of the result is always h + 1 minus l and the result isundefined when h lt l

Bit-string addition does not require the arguments to be of the same size and it gives anon-truncated result For example

lsquo0s101 + 0s1rsquo = lsquo0s110rsquo and lsquo0s101 + 0s11rsquo = lsquo0s1000rsquo

The operation ltlt performs a left-shift for example lsquo0s1101 ltlt 2rsquo = lsquo0s110100rsquo The oper-ation lsquorsquo is bit-string concatenation and lsquo^rsquo is duplication for example

lsquo0s101 0s11rsquo = lsquo0s10111rsquo and lsquo0s101 ^ 3rsquo = lsquo0s101101101rsquo

Regular list operations work as one would expect over bit-strings for example lsquoHead (0s101)rsquois a valid expression with value lsquotruersquo

A7 Characters and StringsThe following built-in functions are available for characters and strings

is alphabetic IsAlpha char rarr boolis alpha-numeric IsAlphaNum char rarr boolis decimal digit IsDigit char rarr boolis hexadecimal digit IsHexDigit char rarr boolis lowercase IsLower char rarr boolis uppercase IsUpper char rarr boolparse binary FromBinString string rarr num optionparse decimal FromDecString string rarr num optionparse hexadecimal FromHexString string rarr num optionconvert to lowercase ToLower string rarr stringconvert to uppercase ToUpper string rarr string

The following string operations are useful for parsing

split from the left splitl (char rarr bool) times string rarr string times stringsplit from the right splitr (char rarr bool) times string rarr string times stringsplit into fields fields (char rarr bool) times string rarr string listsplit into tokens tokens (char rarr bool) times string rarr string list

These are based on the SML functions Substringsplitl Substringsplitr Stringfieldsand Stringtokens Character predicates are declared using special syntax for example theexpression

splitl space or hexdigit and not in set a f ( 12bcab)

gives the result lsquo( 12bc ab)rsquo

26

A8 Floating-pointThe L3 language does not provide specialised types for representing floating-point numbersHowever 32-bit (single precision) and 64-bit (double precision) bit-vector values can be treatedas floating-point numbers the following IEEE compliant encoding formats are assumed

31 30 23 22 0

s e m1 8 23

63 62 52 51 0

s e m1 11 52

Here lsquosrsquo is the sign bit (set to lsquo1rsquo for negative numbers) lsquoersquo is a biased exponent value and lsquomrsquo is thesignificand The following constants and operations are available (where lsquofprsquo stands for bits(32)or bits(64) depending on the name of the operation)

rounding modes roundTiesToEvenroundTowardPositiveroundTowardNegativeroundTowardZero

ieee_rounding

flags (record) DivideByZero InvalidOpOverflow PrecisionUnderflow

ieee_flagsrarrbool

comparison values FP_LT FP_EQ FP_GT FP_UN ieee_compare

convert format FP32_ToFP64 fp32rarrfp64convert format FP64_ToFP32 ieee_roundingtimes fp64rarrfp32convert format FP64_ToFP32_ ieee_roundingtimes fp64rarr

ieee_flagstimes fp32from integer FP32|64_FromInt ieee_roundingtimes intrarrfpto integer FP32|64_ToInt ieee_roundingtimes fprarrint optionfrom string FP32|64 stringrarrfp

negative zero FP32|64_NegZero fppositive zero FP32|64_PosZero fpnegative infinity FP32|64_NegInf fppositive infinity FP32|64_PosInf fpa quiet NaN FP32|64_qNan fpa signalling NaN FP32|64_sNan fp

is integral FP32|64_IsIntegral fprarrboolis finite FP32|64_IsFinite fprarrboolis NaN FP32|64_IsNan fprarrboolis signalling NaN FP32|64_IsSignallingNan fprarrboolis normal FP32|64_IsNormal fprarrboolis sub-normal FP32|64_IsSubnormal fprarrboolis zero FP32|64_IsZero fprarrbool

27

comparison FP32|64_Compare fptimes fprarrieee_compareequality FP32|64_Equal fptimes fprarrboolless than FP32|64_LessThan fptimes fprarrboolless than or equal FP32|64_LessEqual fptimes fprarrboolgreater than FP32|64_GreaterThan fptimes fprarrboolgreater than or equal FP32|64_GreaterEqual fptimes fprarrbool

absolute FP32|64_Abs fprarrfpnegation FP32|64_Neg fprarrfpsquare root FP32|64_Sqrt ieee_roundingtimes fprarrfp(with flags) FP32|64_Sqrt_ ieee_roundingtimes fprarrieee_flagstimes fpaddition FP32|64_Add ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Add_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpsubtraction FP32|64_Sub ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Sub_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpmultiplication FP32|64_Mul ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Mul_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpfused multiply-add FP32|64_MulAdd ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulAdd_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpfused multiply-sub FP32|64_MulSub ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulSub_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpdivision FP32|64_Div ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Div_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fp

The L3 interpreter supports evaluation for 32-bit and 64-bit floating-point expressions but onlywhen running on an x86 machine that supports SSE2 extensions (Pentium 4 and later) Thefused multiply-addsub operations can only be interpreted on machines supporting the FMAextension which came in with the 4th generation (Haswell) Intel processors These restrictionsalso apply to any Standard ML code that is generated by L3

The IEEE 754 standard permits a number of different ways to flag underflow L3 predomi-nantly supports the x86 interpretation which detects underflow after rounding However whenexporting to HOL4 it is possible to choose detection before rounding which for example issuited to ARM instruction set models

A9 Miscellaneous operationsThe following operations are available

pair constructor αtimes β rarr αtimes βfirst of pair Fst αtimes β rarr αsecond of pair Snd αtimes β rarr β

casting [middot] α rarr βinitialise a map InitMap α rarr (βrarrα)

28

option constructor Some αrarrα optionoption projection ValOf α option rarr αoption test IsSome α option rarr bool

set membership in αtimesα set rarr boolset non-membership notin αtimesα set rarr boolset insertion insert αtimesα set rarrα setset union Union α settimesα set rarrα setset intersection Intersect α settimesα set rarrα setset difference Difference α settimesα set rarrα setset subset test IsSubset α settimesα set rarr boolset cardinality Cardinality α setrarr natset from a list SetOfList α list rarrα set

empty list Nil α listlist constructor Cons αtimesα list rarr α listlist head Head α list rarr αlist tail Tail α list rarr α listlist length Length α list rarr natlist concatenation α listtimesα list rarr α listlist flatten Concat α list list rarr α listlist element Element nattimesα list rarr αlist prefix Take nattimesα list rarr α listlist drop prefix Drop nattimesα list rarr α listlist pad left PadLeft αtimes nattimesα list rarr α listlist pad right PadRight αtimes nattimesα list rarr α listlist update Update αtimes nattimesα list rarr α listlist difference Remove α listtimesα list rarr α listlist intersection RemoveExcept α listtimesα list rarr α listlist without duplicates RemoveDuplicates α listrarr α listlist membership IsMember αtimesα list rarr boollist member position IndexOf αtimesα list rarr nat option

Sets are only defined over equality types see Appendix A2 The casting map is defined overcast-able types (as represented by the polymorphic type variables α and β) these are the primitivetypes (with the exception of lsquounitrsquo) and user defined enumerated types Assume lsquoEnumrsquo and lsquoEnum2rsquoare declared with

construct Enum One Two Three construct Enum2 Four Five Six Seven

The cast operations are described in Tables 1 to 7

29

Table 1 Cast to lsquoboolrsquo

From Operation Examples

bool identity lsquo[true]boolrsquo = lsquotruersquostring parse bool lsquo[true]boolrsquo = lsquotruersquo

lsquo[false]boolrsquo = lsquofalsersquootherwise undefined

nat is not zero lsquo[0n3]boolrsquo = lsquotruersquolsquo[0n0]boolrsquo = lsquofalsersquo

int is not zero lsquo[-0i1]boolrsquo = lsquotruersquolsquo[0i0]boolrsquo = lsquofalsersquo

bool list is not zero lsquo[0s11]boolrsquo = lsquotruersquolsquo[0s0]boolrsquo = lsquofalsersquo

bits(middot) is not zero lsquo[3`3]boolrsquo = lsquotruersquolsquo[0`3]boolrsquo = lsquofalsersquo

Enum is not the first element lsquo[One]boolrsquo = lsquofalsersquolsquo[Two]boolrsquo = lsquotruersquo

Table 2 Cast to lsquostringrsquo

From Operation Examples

bool name lsquo[true]stringrsquo = lsquotruersquostring identity lsquo[hello]stringrsquo = lsquohellorsquonat decimal lsquo[0n3]stringrsquo = lsquo3rsquoint signed decimal lsquo[-0i1]stringrsquo = lsquo~1rsquobool list binary lsquo[0s11]stringrsquo = lsquo11rsquobits(middot) unsigned hexadecimal lsquo[139`8]stringrsquo = lsquo8BrsquoEnum name lsquo[One]stringrsquo = lsquoOnersquo

30

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

16 MapsMaps are used to represent total functions4 For example the declaration

type map nat -gt int -- a map type pseudonym

introduces a type pseudonym for maps with domain lsquonatrsquo and codomain lsquointrsquo Maps and singlemap entries can be assigned to for example given the declaration

declare -- three global maps

m1 mapm2 mapm3 nat -gt nat

the statement m1 lt- m2 m1(1) lt- 2

will set map lsquom1rsquo to be lsquom2rsquo and this map is then updated so that lsquom1(1)rsquo takes value lsquo2rsquoThe language encourages the use of simple un-curried maps which means that the type

type map bool nat -gt int

should be used in preference totype nmap nat -gt inttype map bool -gt nmap

In particular the language does not permit the syntax lsquom(true)(2)rsquo whereas lsquom(true 2)rsquo is fineThe language does not provide a mechanism for specifying anonymous functions or anonymous

maps5 Furthermore maps and operations (either primitive or user defined) are considered to bedistinct As such it is not possible to make assignments of the form lsquom3 lt- Log2rsquo

17 Sum TypesEnumerated and sum (tagged union) types can be introduced using the lsquoconstructrsquo keywordFor example the declaration

construct enumerated Zero One Two Three -- a new type called enumerated

introduces a new type lsquoenumeratedrsquo that consists of four elements (new constants) Sum typescan be declared in a similar manner for example

construct bool_option BoolNone BoolSome bool -- an unnecessary variant of bool option

The elements of this new type are lsquoBoolNonersquo lsquoBoolSome(false)rsquo and lsquoBoolSome(true)rsquo6 Everyconstructor of the sum type must map from a pre-existing type (or be nullary) and this precludesthe definition of new recursive or mutually recursive datatypes

Enumerated types (where every constructor is nullary) admit casting tofrom numeric types7For example lsquo[One]natrsquo is equal to lsquo0n1rsquo and lsquo[0n1]enumeratedrsquo is equal to lsquoOnersquo

4Maps must have an equality type as their domain They can be viewed as a form of array and are typically usedto model memories and register banks

5The function lsquofn x =gt x + 1rsquo is an example of an anonymous function in Standard ML6The brackets are needed here for example lsquoBoolSome truersquo will not parse7The same does not hold for general sum types

4

18 RecordsRecord types can be introduced using the lsquorecordrsquo construct The following is an example of arecord declaration

record rec

number natinteger intboolean bool

Every value of type lsquorecrsquo has three components which may be accessed using dot notation forexample if we have a global variable

declare rec rec

then the sub-elements are lsquorecnumberrsquo lsquorecintegerrsquo and lsquorecbooleanrsquo The language does notprovide a syntax for record literals As such records must be built up incrementally for examplethe following is a sequence of assignments to components of the variable lsquorecrsquo

recnumber lt- 1 recinteger lt- 2 recboolean lt- true

It is not possible to express this with a single assignment to lsquorecrsquo

19 RegistersRegister types can be introduced using the lsquoregisterrsquo construct for example

register sreg bits(32)

31-28 FLAGS7-0 27-16 MODE15-12 MASK

This declares a new type lsquosregrsquo that represents the following 32-bit register31 28 27 16 15 12 11 8 7 0

FLAGS MODElt110gt MASK MODElt1912gt

Note that the bit-field 118 of lsquosregrsquo does not correspond with a named component Also notethat fields are allowed to be non-contiguous which is the case for the lsquoMODErsquo field Register typesare essentially special forms of record types with the automatic specification of bijections toa bit-vector representation Each named bit-field can be accessed using the dot notation forexample if we have

declare status sreg

then the fields lsquostatusFLAGSrsquo and lsquostatusMASKrsquo have type lsquobits(4)rsquo and lsquostatusMODErsquo has typelsquobits(20)rsquo Unlike records register types automatic admit casting tofrom an underlying bit-vector type The expression lsquoampstatusrsquo gives the value of the register (with type lsquobits(32)rsquo) andlsquosreg(0xFFFF0000)rsquo constructs a register of type lsquosregrsquo It is possible to use this notation to updatearbitrary bit-fields of a register for example the statement

ampstatuslt207gt lt- 11101101100111

will update the bit-field 207 of lsquostatusrsquo using the 14-bit literal value

5

110 Polymorphic TypesUsers cannot declare their own polymorphic types Furthermore all user defined operations andvariables must be monomorphic The language does however provide support for three built-inpolymorphic datatypes which may be used under the proviso that these types are always fullytype instantiated (free of type variables)

1101 ListsThe language provides limited support for working with lists Lists can be specified as follows

list 0n0 2 4 -- a list of naturals (length three)0n0 2 3 Nil -- expanded versionCons (0n0 Cons (2 Cons (4 Nil))) -- equivalent version

These expressions have type lsquonat listrsquo Given the first-order nature of L3 only simple listoperations are provided (for example lsquoHeadrsquo lsquoTailrsquo and lsquoLengthrsquo) Higher-order list operationssuch as filter map and fold are not available

1102 Finite SetsThe language provides basic support for finite sets Sets can be specified as follows

set 0n0 2 4 -- a three element set (of naturals)0n0 insert 2 insert 4 insert set -- an expanded versionSetOfList (list 0n0 2 4 ) -- a version built from a list

These expressions have type lsquonat setrsquo The infix operators lsquoinrsquo and lsquonotinrsquo test for set member-ship for example the expressions

0n0 in set 0 2 4 -- test for membership0n1 notin set 0 2 4 -- test for non-membership

both evaluate to lsquotruersquo Sets can only be defined over equality types It is not possible forexample to construct the type lsquo(bool -gt bool) setrsquo

1103 Option TypesThe option type is a polymorphic sum type that has two constructors lsquoNoneα optionrsquo andlsquoSomeαrarrα optionrsquo Option types are helpful when specifying partial operations

111 Statements and ExpressionsThis section presents the statements and expressions of the language Statements can be groupedinto blocks using the syntax

statement1 -- do thisstatement2 -- then do thismiddot middot middot

6

Each block and sub-statement has type lsquounitrsquo The operator lsquorsquo is strictly binary trailing semi-colons not permitted at the end of a sequence of statements Expressions are distinct fromstatements in particular expressions preclude assignments

1111 NothingThe statement lsquonothingrsquo has no effect Its primary purpose is to facilitate the specification ofcontrol flows wherein some paths do something (update the state) and others do nothing8

1112 ConditionalsThe language supports if-then-else statements and expressions and when-do statements Thelatter is provided as a convenient shorthand that is to say the statement

when p do x

is equivalent to the statement

if p then x else nothing

Note that the language does not support layout syntax (the off-side-rule)

1113 For LoopsThe language provides support for simple for-loop statements On each iteration of a for-loopa natural number index variable is either incremented or decremented (by one) This process isrepeated until the index value reaches a pre-computed upper or lower bound for example theloop statements

for i in 1 3 do proc(i)for i in 3 1 do proc(i)

are respectively equivalent to

proc(1) proc(2) proc(3) proc(3) proc(2) proc(1)

The initial and final loop index values may be arbitrary natural number expressions As suchit may be the case that the loop direction will only be known once these bound expressions arecomputed

In addition to regular for loops the language also supports foreach loops which operate overlists For example the following code makes three calls to lsquoprocrsquo

foreach i in list 0n2 4 6 do proc(i)

Note that this construct will also work for bit-strings and for normal stringsThere is no support for do while or repeat until loops

8The lsquonothingrsquo statement is essentially syntactic sugar for lsquo()rsquo

7

1114 Exceptions Unknown and UndefinedThe keyword lsquoUNKNOWNrsquo is used to represent an unspecified element which may be of any giventype The language does not stipulate whether or not this value should be chosen deterministi-cally If the value were chosen deterministically then the expression lsquoUNKNOWN == UNKNOWNrsquo willalways be lsquotruersquo However if the choice is non-deterministic then there is no way of knowing ifan occurrence of this expression is lsquotruersquo or lsquofalsersquo

The language supports user defined exceptions which may be raised but not caught Thelsquoexceptionrsquo keyword is used to declare new exception categories for example

exception ASSERT string

introduces a new exception lsquoASSERTrsquo that takes a single string as an argument This exception canbe raised in expressions and statements as follows

ASSERT (an error has occurred)

Thus exceptions can be used to flag the occurrence of a variety of different errors The L3interpreter will stop when an exception is raised Exceptions can be raised within expressionsand are not constrained by return type

The behaviour of various operations is undefined on some inputs for example the arithmeticexpression lsquox div 0n0rsquo is undefined For any given undefined expression the language permitsthree possible interpretations (implementations)

bull A deterministic value can be chosen For example lsquox div 0n0rsquo is equal to lsquo0n0rsquo is a validinterpretation of this undefined expression

bull A non-deterministic value can be chosen In particular is not necessary for the expressionlsquox div 0n0 == x div 0n0rsquo to be lsquotruersquo

bull An exception can be raised

It is expected that specifications will be designed with some preferred treatment of undefinedbehaviour in mind In this example one possible way to manage undefined cases is by takingcare to explicitly write code of the form lsquoif n == 0 then else x div n rsquo This willensure that undefined cases are unreachable

1115 Procedure CallsA procedure is any user defined operation with return type lsquounitrsquo Procedures typically providefunctionality by means of updating the global state (through side effects) Procedures can becalled (and exceptions can be raised) in statement blocks for example

middot middot middotproc (1 true) -- this is a procedure callmiddot middot middot

The following code is valid but not recommended

8

middot middot middotASSERT error -- raise an exceptionproc (1 true) -- the L3 interpreter will never reach this code

In the above the exception is unconditionally raised so the remaining code should be regardedas unreachable (redundant)

1116 Local VariablesThe L3 language supports two varieties of variables mutable and immutable All global vari-ables are mutable The keyword lsquovarrsquo is used to declare new mutable variables with local scopeLocal variables can be introduced anywhere within a statement block and these variables canbe assigned to using the lsquolt-rsquo operator Immutable variables are introduced within a block usingthe syntax lsquox = expr rsquo and this is treated as a let-statement An immutable value cannot beupdated however it can fall out of scope by declaring a new immutable variable with the samename The operators lsquolt-rsquo and lsquo=rsquo are not permitted in expressions

The specification below uses two mutable variables lsquoxrsquo and lsquoyrsquo

var y = zvar x = yif p then xlt30gt lt- 1111 y lt- x + 1

else xlt74gt lt- 1111 y lt- 0 return (x + y)

This could be respecified using immutable variables for example

y = zx = yx y = if p then (x || 00001111 x || 00001111 + 1)

else (x || 11110000 0)return (x + y)

It is not always easy to eliminate mutable variables In this case the second specification ismore cumbersome because the bit-field update has been replace by an explicit mask (bitwise-or)operation This operations has been repeated in specify the value of lsquoyrsquo because assignments arenot permitted in expressions

Mutable variables can be declared without an initial assignment for example lsquovar xrsquo isequivalent to lsquovar x = UNKNOWNrsquo

1117 PatternMatchingThe language supports match statements and expressions Pattern matching is supported withrespect to literals (see Section 13) constructors9 (immutable) variables wildcards (anonymousvariables) and bit-patterns

9This includes matching on tuples as well as lsquoNonersquo lsquoSomersquo lsquoConsrsquo and lsquoNilrsquo Matching on finite sets and recordfields is not possible

9

Given the type declarations

construct enum One Two Three construct data

NoDataData1 string bits(8)Data2 enum bits(16)

the following illustrates a match expression

match y

case -1 NoData or -2 NoData =gt 0`4 -- note use of orcase _ Data1 (hello 11 x 11) =gt x + 1 -- use of bit-patterncase i Data2 (Three 1111 y) =gt [i] + ylt30gtcase 1 Data2 (_ 8) =gt 4case _ =gt 8

The body (right-hand side of lsquo=gtrsquo) of the first case line with a matching pattern is selected Thesymbol lsquo_rsquo is a wildcard and will match any value The lsquoorrsquo construct provides a shorthand forwriting blocks of clauses with differing patterns but the same body

The terms lsquo11 x 11rsquo and lsquo1111 yrsquo are called bit-patterns and they will match against a setof bit-vector values From the type declaration of lsquodatarsquo it is known that the variable lsquoxrsquo mustrepresent a 4-bit value because it occurs in the middle of an 8-bit word (the match requires bitslsquo11rsquo as a prefix and as a suffix) Likewise lsquoyrsquo must be a 12-bit value Multiple variables can occurin a bit-patterns for example lsquo1 x 1 y 0rsquo is a valid bit-pattern The type checker will oftenbe able to infer the type of pattern variables and if this fails type annotations can be added

The lsquopatternrsquo construct can help avoid situations where explicit annotations are repeatedlyrequired (causing clutter in patterns) If for example the variable lsquoimm5rsquo is frequently used tomatch a 5-bit value then the following declaration can be made

pattern imm5 bits(5)

In subsequent code the default type for pattern variable lsquoimm5rsquo will be lsquobits(5)rsquo The lsquopatternrsquoconstruct only influences type checking If a particular type hint is no longer appropriate thenit can be dropped for example one can insert the declaration lsquoclear pattern imm5rsquo

112 Defining Constants and OperationsUsers can construct operational semantics style formal specifications in L3 by defining their ownconstants and operations There is no module system or facility for local definitions all userdefinitions are made at the top-level with global scope User constants and operations cannot beoverloaded or redefined

A pure constant is a nullary (zero argument) operation that is state independent for examplethe following code declares a new constant

bits(32) UINT_MAX = 0xFFFFFFFF

10

The following code declares operations that are nullary but state dependent

declare number Natnat numberPlus1 = return (number + 1)unit incNumber = number lt- numberPlus1

Users can also declare new unary operations which may or may not be state dependent forexample

nat numberMinusN (nnat) = return (number + n) -- state dependentunit decNumber () = number lt- numberMinusN (1)nat mla (mnatnnatanat) = return (m n + a) -- pure

The operation lsquomlarsquo is unary because it takes a single triple as an argument To enhance clarityand avoid misunderstandards users may elect to specify nullary state dependent operations usinga single lsquounitrsquo argument Given the declarations above the expression lsquodecNumber()rsquo gives theclear impression that a call is being made (with possible side-effects) wheres the expressionlsquoincNumberrsquo does not

At the point of declaration operation arguments must be fully type annotated and onlymonomorphic types are allowed10 It is nevertheless possible to declare bit-vector operationsthat are valid with respect to some given set of bit widths for example the following are validdeclarations

--- valid for any bit-vector width N ---bits(N) bv_mla (mbits(N) nbits(N) abits(N)) = return (m n + a)

--- valid for sufficiently wide bit-vectors (N greater than eight) ---bool bit8 (xbits(N)) with N gt 8 = return (xlt8gt)

An L3 type error will arise if ever an application of the operation lsquobit8rsquo violates the bit widthconstraint Note that vector width variables (such as lsquoNnatrsquo above) can be used as if they werea regular variables in the definitional body of an operation

113 ComponentsWhen specifying instruction set architectures the two most significant programmerrsquos modelcomponents are typically the main memory and a collection of general purpose registers In theMIPS architecture for example there are thirty-two general purpose registers which may berepresented using the following map

declare gpr bits(5) -gt bits(64)

The statement

gpr(d) lt- gpr(r)10An compile time error will arise if the type checker is not able to infer all types the final definition must be

free of type variables

11

then expresses moving a value from register lsquorrsquo to register lsquodrsquo However register a memory accessis frequently more complicated than this in particular registers can be banked and memory canbe complex11 As such it is often necessary to specify collections of operations for accessing(reading and writing) these components With the MIPS example register zero is special (it isa constant value) and so one could define the following operations

bits(64) read_gpr (nbits(5)) = if n == 0 then 0 else gpr (n)unit write_gpr (vbits(64) nbits(5)) = when n ltgt 0 do gpr (n) lt- v

Thus the previous register transfers would now be specified as follows

write_gpr (read_gpr (n) d)

This precise style of specification is not entirely satisfying though since it departs in appearancefrom the pseudo code found in MIPS reference manuals The L3 language provides a specialmechanism for specifying a pair of operations that read and write state components With theMIPS example the following declaration can be made

component GPR (nbits(5)) bits(64)

value = if n == 0 then 0 else gpr(n)assign value = when n ltgt 0 do gpr(n) lt- value

One can then write

GPR(d) lt- GPR(r)

which is closer to the syntax used in the MIPS reference manuals The lsquocomponentrsquo constructeffectively provides a controlled form of operator overloading whereby the lsquoassignrsquo operation12

is select when the operator name appears on the left-hand side of an assignment (lsquolt-rsquo) and thelsquovaluersquo operation13 is applied otherwise Semantically these two operations are exactly the sameas the manually defined versions lsquowrite_gprrsquo and lsquoread_gprrsquo The ldquowriterdquo operation will alwayshave a lsquounitrsquo return type Users are free to specify the ldquoreadrdquo and ldquowriterdquo operations in any mannerthat they deem appropriate however the ldquowriterdquo operation cannot be defined recursively norcan the ldquoreadrdquo operation call the ldquowriterdquo operation

114 RecursionThe language permits the definition of recursive operations It is not possible to define mutuallyrecursive operations

The L3 language has been designed to act as an authoring front-end for the HOL4 theoremprover facilitating the task of writing instruction set specifications In order to successfullyimport an L3 specification it is necessary for the HOL4 system to prove that every user defined

11ARM registers are banked according to processor mode Memory can often be accessed with big- and little-endian byte ordering Special treatment may be needed for unaligned memory addresses for example when readinga 16-bit value from an odd address There may also be address translation (virtualisation) and memory hierarchies(caching)

12In this example the ldquowriterdquo operations is internally called lsquowriteGPRrsquo13Internally the ldquoreadrdquo operation is simply called lsquoGPRrsquo

12

operation is total (terminates on all inputs) If an L3 function is non-terminating then it willbe impossible to export that definition to HOL4 If a function is terminating but the standardautomation of HOL4 is unable to construct a termination proof then it may be necessary toprovide the prover with a hint in the form of a measure

Consider the following specification

declare m bits(8) -gt bits(8)

unit load (abits(8) lbits(8) list) =match l

case Nil =gt nothingcase Cons (h t) =gt m(a) lt- h load (a + 1 t)

The lsquoloadrsquo operation recurses over the list lsquolrsquo loading values into the map lsquomrsquo At the time ofwriting this documentation trying to build the exported HOL4 version of this specificationgives rise to the following error message

Initial goal

existRWF R andforallstate a l h t

(l = ht) rArrR ((a + 1wt)state with m = (a =+ h) statem) ((al)state)

Exception raised at TotalDefnDefinebetween beginning of frag 0 and end of frag 0at TotalDefndefnDefine

Unable to prove termination

Try using TotalDefntDefine ltnamegt ltquotationgt lttacgt

This occurs because HOL4 is unable to automatically prove that lsquoloadrsquo always terminates Toget around this problem the original L3 specification can be modified to contain an annotationas follows

unit load (abits(8) lbits(8) list) measure Length(l) =

The metadata lsquomeasure Length(l)rsquo tells HOL4 to examine the length of the list lsquolrsquo since thisvalue will decrease upon each recursive call to lsquoloadrsquo When the length of the list is zero (thelsquoNilrsquo case) there are no recursive calls so termination is guaranteed

The expression occurring after the lsquomeasurersquo keyword must be of type lsquonatrsquo After provid-ing a measure it is still possible that HOL4 will fail to prove termination either because thesupplied measure is incorrect or because the termination proof is non-trivial (requires humanguidance andor custom lemmas) If this occurs then users should either simplifyrewrite theirspecifications or if necessary report the problem

13

115 Instruction Set DefinitionsWhen working with instruction set models it is helpful to construct a datatype that representsthe set of machine (low-level) instructions This datatype constitutes a simple form of abstractsyntax tree (AST) and it can be used to build instruction decoders (identifying machine-codeinstructions and splitting opcodes into sub-fields) instruction encoders (generating opcodes fora given instruction) next-state functions (applying a semantics function for a given instruction)and assembly code parsers

By way of an example consider the MIPS instruction ANDI this instruction has the assemblycode syntax

ANDI rt rs immediate

and the following 32-bit machine-code encoding

31 26 25 21 20 16 15 0

001100 rs rt immediate6 5 5 16

The semantics of this instruction can be expressed with the operation

unit run_ANDI (rsbits(5) rtbits(5) immbits(16)) =GPR(rt) lt- GPR(rs) ampamp ZeroExtend (imm)

One could use this operation to directly specify a next-state function which would be of theform

unit Next =match Fetch -- fetches a 32-bit opcode from memory

middot middot middotcase 001100 rs rt imm =gt run_ANDI (rs rt imm)middot middot middot

This style of specification is direct and concise however it does lack some of the flexibility thatcomes with using an instruction datatype The L3 language provides support for an slightlydifferent style of specification This alternative approach is explained by first examining howone would specify things manually (explicitly) and then showing how L3 can streamline thisprocess

Firstly one could explicitly define an AST datatype for MIPS instructions it would be ofthe form

construct instruction

middot middot middotANDI bits(5) bits(5) bits(16)middot middot middot

14

This datatype provides a suitable constructor for the ANDI instruction It is now possible to definea decoder which maps opcodes onto AST entries for example

instruction Decode (opcbits(32)) =match opc

middot middot middotcase 001100 rs rt imm =gt ANDI (rs rt imm)middot middot middot

This decoder can be used to define our next-state function that is

unit Next = Run (Decode (Fetch))

where lsquoRunrsquo is defined by

unit Run (iinstruction) =match i

middot middot middotcase ANDI (args) =gt run_ANDI (args)middot middot middot

When working with full-scale architecture specifications (where the AST type is large) thereare some clear overheads associated with implementing this approach (in comparison with theAST free version) It becomes challenging to maintain the AST datatype declaration and tokeep it correctly synchronised with the instruction semantics operations (such as lsquorun_ANDIrsquo)and the definition of lsquoRunrsquo Note however that there is great uniformity in the AST datatypedeclaration and also in the definition of lsquoRunrsquo As such L3 is able to automatically define bothof these for the user

To make use of this automation the declaration of lsquorun_ANDIrsquo is simply modified to

define ANDI (rsbits(5) rtbits(5) immbits(16)) =GPR(rt) lt- GPR(rs) ampamp ZeroExtend (imm)

The lsquodefinersquo keyword tells L3 to define a semantics function14 (as before) and to also create anew lsquoinstructionrsquo datatype AST entry furthermore the two will be linked with the automaticconstruction of a lsquoRunrsquo function The lsquoinstructionrsquo type and lsquoRunrsquo function become defined (inscope) following the declaration lsquodefine Runrsquo After this declaration it is no longer possible touse the lsquodefinersquo construct again however it does become possible to define functions such aslsquoDecodersquo and lsquoNextrsquo

Specifications that are based on using lsquodefinersquo gain the benefits of declaring an instructionAST datatype without the downside of laborious coding overheads In the example above theoverhead amounts to one extra line of code this comes from defining a next-state function thatcalls the dedicated decode function followed by a call to lsquoRunrsquo

One of the key advantages of declaring an instruction datatype is that it makes it consider-ably easier to develop tools that work with assembly code syntax (performing parsing encoding

14This function is internally called lsquodfnANDIrsquo instead of lsquorun_ANDIrsquo

15

and pretty-printing) In this case it is relatively easy for example to map between the MIPSinstruction syntax andi $5 $6 1024 and the expression lsquoANDI (5 6 1024)rsquo Defining anencoder in L3 is relatively straightforward for example

bits(32) Encode (iinstruction) =match i

middot middot middotcase ANDI (rs rt imm) =gt 001100 rs rt immmiddot middot middot

Such a function can be used to write a MIPS assembler which would map the assembly codesyntax andi $5 $6 1024 onto the machine-code value 0x30c50400

2 TutorialThis section gives a brief overview of how to install and use L3

Installation The sources for L3 can be downloaded from the following webpage

wwwclcamacuk~acjf3l3

The file l3tarbz2 can be unpacked with the command

$ tar xvjf l3tarbz2

This will create a directory of the form L3-YYYY-MM-DD where the year month and day willcorrespond with the release date The current version of L3 depends upon PolyML 57 whichcan be obtained from the site polymlorg If PolyML is installed then L3 can be built as follows

$ cd L3-YYYY-MM-DD$ make

Once built the following should appear when you start L315

$ l3ltlt L3 gtgtgt

Users should consider running L3 with the command rlwrap l316

15This assumes that the directory L3-YYYY-MM-DDbin has been added to the PATH environment variable16Details on rlwrap utility can be found at the site freecodecomprojectsrlwrap

16

Basic Interaction The command prompt for L3 is essentially the read-eval-print loop (REPL)of PolyML As such users are free to write arbitrary Standard ML code The structure Runtimeenables interaction with L3 The following shows an arithmetic evaluation in Standard ML aswell as in the L3 interpreter (evalQ)

gt 1 + 2val it = 3 intgt RuntimeevalQ `0i1 + 2`val it = `0i3` Termterm

Various error messages can occur when using the interpreter for example

gt RuntimeevalQ `1 + 2`Exception- Fail Could not infer all types raised

gt RuntimeevalQ `0i2 div 0`Exception- Except (Div SOME (div (int [`0i2` `0i0`]))) raised

The first error occurs because unannotated number literals are regarded as bit-vector values andhere the vector width cannot be inferred

L3 declarations can be made using the function loadQ The following sequence shows thedeclaration and manipulation of a global variable

gt RuntimeloadQ `declare n nat`ltVARgt nval it = () unit

gt RuntimeevalQ `n`val it = `UNKNOWNnat` Termterm

gt RuntimeevalQ ` n lt- 3 n `val it = `0n3` Termterm

The global state can be examined using the function show for example

gt Runtimeshow()val it = [(n `0n3`)] Evalterm_stack

The state can be ldquowipedrdquo clean using the function reset and all declarations can be wiped usinglsquoresetAllrsquo for example

gt Runtimereset()val it = () unitgt Runtimeshow()val it = [(n `UNKNOWNnat`)] Evalterm_stack

gt RuntimeresetAll()val it = () unitgt Runtimeshow()val it = [] Evalterm_stack

The function lsquoLoadQrsquo is similar to lsquoloadQrsquo but it performs a lsquoresetAllrsquo before making declarations

17

Constants The structure Consts provides various functions for working with L3 constantsMany of the operation in the Consts structure will be of little interest to end-users however itcan be used to display some helpful information

The function ConstslookupConst can be used to lookup an operation for example

gt ConstslookupConst Log2val it = Primitive [(bits(a) -gt bits(a) -) (nat -gt nat -)] const

Since lsquoLog2rsquo is a primitive operation only the valid types (ordered by overload priority) are showWith user operations the internal representation (definition) of the operation will be shownfor example

gt RuntimeLoadQ `unit demo () = ()`gt ConstslookupConst demoval it = Definition (Abs ([(_ (unit -))] unit -gt unit `()`) NONE 1)

Constsconst

The functions ConstslistDefinitions and ConstslistExceptions provide details of all useroperations and exceptions respectively The function lsquoConstsstatsrsquo gives a summary of all thecurrent declarations

gt Constsstats()Primitives 188Destructors 5Constructors 0Accessors 0Exceptions 0User operations 1Instruction definitions 0

Here the constructors for primitive types (such as lsquoConsrsquo) are counted under ldquoprimitivesrdquo

Types The Types structure can be used to display information relating to L3 types In partic-ular this structure provides the functions TypeslookupConst and TypeslistConsts which aredemonstrated below

gt RuntimeloadQ `construct enum One Two Three`gt TypeslistConsts()val it =

[(enumeq = true ast = false def = Constructors (Enum ltdict(3)gt) num = 0)]

(string typeconst) list

gt TypeslookupConst intval it = SOME eq = true ast = false def = BaseType num = ~1

typeconst option

18

Loading and Exporting Specifications When writing an L3 specification it is expected thatuser declarations will be contained in an L3 source file A sample instruction set specification(tinyspec) can be found in the L3 distribution subdirectory examples This specification isbased on Thackerrsquos pedagogical Tiny 3 architecture it can be loaded as follows

gt RuntimeLoadF tinyspecLoading tinyspecltTYPgt regTltTYPgt wordTmiddot middot middotltFUNgt test_progDone

The string argument to the functions RuntimeloadF and RuntimeLoadF can be in the form ofa comma separated list of files which will be loaded in order That is the call

RuntimeloadF aspec bspec

will load aspec followed by bspecThe function HolExportexport will export the current L3 specification in the form of an

HOL4 script for example

gt HolExportexport tinyraiseexception okfunction okmiddot middot middotmextend skipmunextend skipCreated file tinyScriptsmlCreated file tinyLibsmlCreated file tinyLibsigDone

The function HolExportspec provides a convenient shortcut for performing LoadF and exportusing just a single call for example HolExportspec (tinyspec tiny) will perform theload and export presented above

L3 is capable of exporting two styles of HOL specification an explicitly monadic version(based on state_transformerTheory) and a version that directly manipulates state using let-expressions (which is the default style) For example a monadic version of the Tiny specifi-cation can be exported using the command HolExportspec (tinyspec tiny monadic)Other export options include sigdocs nosigdocs (for setting HOLrsquos TheoryPPinclude_docstrace variable) bigrecords nobigrecords (for controlling HOLrsquos Datatypebig_record_size)and underflowbefore nounderflowbefore (for selecting the required IEEE 754 underflow be-haviour)

Generated HOL4 specifications are not designed to be manually edited (or human readable)To build an L3 specification script the HOL library Import is needed This library is currentlylocated in the directory $HOL_DIRexamplesl3-machine-codecommon and so adding this path tothe INCLUDES variable of a local Holmakefile is recommended The examplesl3-machine-codedirectory contains various examples of using L3 generated specifications

19

Testing Specifications Having written an L3 specification it is fairly easy to write code (inStandard ML) that runs test vectors Code for running the tinyspec example can be found inthe file run-tinyspec In this test harness the Tiny state is initialised and a small test programis loaded simply by evaluating the expression lsquoinitialize (test_prog)rsquo

It is also possible to evaluate (run) models that have been exported to HOL4 The filerun-tinysml shows how this can be accomplished for the Tiny example

20

A Primitive Types and OperationsThe primitive types are as follows

unit bool char nat int bits(middot) rounding

There are two infix type constructors lsquorsquo for pairs and lsquo-gtrsquo for maps There are also postfix typeconstructors lsquosetrsquo lsquooptionrsquo and lsquolistrsquo for example sets of strings are represented by the typelsquostring setrsquo The following sections describe these primitive types together with some detailsof associated operations The following constants and operations are available

nullary () Nil None false roundTiesToEven roundTowardNegativeroundTowardPositive roundTowardZero true

prefix - ~ Abs Cardinality Cons Difference Drop Element FP32_AbsFP32_Add FP32_Equal FP32_IsNan FP32_LessThan FP32_MulFP32_Neg FP32_Sub FP64_Abs FP64_Add FP64_Equal FP64_IsNanFP64_LessThan FP64_Mul FP64_Neg FP64_Sub FromBinStringFromDecString FromHexString Fst Head IndexOf InitMapIntersection IsAlpha IsAlphaNum IsDigit IsHexDigit IsLowerIsMember IsSome IsSubset IsUpper Length Log2 Max Min MsbQuotRem Remove RemoveDuplicates RemoveExcept ReverseSetOfList SignExtend SignedMax SignedMin Size Snd Some TailTake ToLower ToUpper Union Update ValOf ZeroExtend not

infix = ampamp + - lt lt+ lt= lt=+ ltgt == gt gt+ gt= gt=+ ^ || gtgtltlt gtgt+ ltlt gtgt and div in insert mod notin or quot rem

sdivsmodother middot ltmiddotgt middot ltmiddotmiddotgt [middot] fields splitl splitr tokens

Many arithmetic operations are overloaded Unless otherwise stated the order of selection islsquobits(middot)rsquo lsquonatrsquo lsquointrsquo and then lsquobool listrsquo

A1 UnitThe type lsquounitrsquo represents the singleton set containing the value lsquo()rsquo The primary use of thistype is as the return type for procedures

A2 BoolThe type lsquoboolrsquo represents the two element set B = lsquotruersquo lsquofalsersquo The following standardBoolean operations are available

negation not bool rarr boolconjunction and booltimes bool rarr booldisjunction or booltimes bool rarr boolequality == αtimesα rarr boolnon-equality ltgt = αtimesα rarr bool

21

The infix operators lsquoandrsquo and lsquoorrsquo are interpreted with short-circuit evaluation for example in theexpression lsquofalse and f()rsquo the value of lsquof()rsquo is not computed as the overall expression will alwaysevaluate to false This short-circuiting influences the side-effects that occur during expressionevaluation

There are two prefix symbols for logical negation (these are semantically identical) with lsquorsquobinding slightly tighter than lsquonotrsquo This distinction is becomes significant when working withequalities for example lsquonot a == brsquo is taken to be not(a = b) whereas lsquoa == brsquo is (nota) = b

Equality is only defined with respect to equality types represented here by the type variableα An equality type is any type built without the used of the map operator lsquo-gtrsquo

A3 NatThe type lsquonatrsquo represents the natural numbers N = 0 1 2 The following operations areavailable

logarithm (base two) Log2 nat rarr natminimum value Min nattimes nat rarr natmaximium value Max nattimes nat rarr natless than lt nattimes nat rarr boolgreater than gt nattimes nat rarr boolless than or equal to lt= nattimes nat rarr boolgreater than or equal to gt= nattimes nat rarr booladdition + nattimes nat rarr natsubtraction - nattimes nat rarr natmultiplication nattimes nat rarr natexponentiation nattimes nat rarr natdivision div nattimes nat rarr natmodulus mod nattimes nat rarr nat

The lsquodivrsquo and lsquomodrsquo operations satisfy the following property

foralln 0 lt n =rArr forallk k = (k div n) lowast n+ (k mod n) and (k mod n) lt n

The expressions lsquoLog2(0)rsquo lsquox div 0rsquo and lsquox mod 0rsquo are all undefined 17

A4 IntThe type lsquointrsquo represents the integers Z = Ncupminus1minus2minus3 The following operations areavailable

17The interpreter will raise an exception when attempting to evaluate them

22

unary minus - int rarr intabsolute value Abs int rarr intminimum value Min inttimes int rarr intmaximum value Max inttimes int rarr intless than lt inttimes int rarr boolgreater than gt inttimes int rarr boolless than or equal to lt= inttimes int rarr boolgreater than or equal to gt= inttimes int rarr booladdition + inttimes int rarr intsubtraction - inttimes int rarr intmultiplication inttimes int rarr intexponentiation inttimes nat rarr intquotient and remainder QuotRem inttimes int rarr inttimes intquotient quot inttimes int rarr intremainder rem inttimes int rarr intdivision div inttimes int rarr intmodulus mod inttimes int rarr int

The operation lsquoAbsrsquo gives an positive integer value for example lsquoAbs(-2)rsquo = lsquo2rsquo The integeroperations lsquoquotrsquo and lsquodivrsquo are related to natural number division as follows

i quot j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

and

i div j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(minusi) div n(j))minus 1 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i and n(i) mod n(minusj) = 0

minus z(n(i) div n(minusj))minus 1 j lt 0 and 0 le i and n(i) mod n(minusj) = 0

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

where z NrarrZ and n ZrarrN are value preserving maps The lsquoremrsquo and lsquomodrsquo operations satisfythe equations

i rem j =

iminus (i quot j) lowast j j = 0

undefined j = 0i mod j =

iminus (i div j) lowast j j = 0

undefined j = 0

A5 Bit-vectorsThe type lsquobits(n)rsquo represents fixed-width (n-bit) words also known as bit-vectors for examplebits(32) is the type of 32-bit machine words18 The bits type can be viewed as representing

18These are called double-words (dword) in the x86 architecture and simply words in the ARM architecture

23

the set Zn = 0 1 2nminus1 for some 0 lt n At the type system level no distinction is madebetween signed and unsigned words however some operations (such as orderings) have signedand unsigned variants

The following bit-vector operations are available

1rsquos complement ~ bits(n) rarr bits(n)2rsquos complement - bits(n) rarr bits(n)absolute value Abs bits(n) rarr bits(n)logarithm (base two) Log2 bits(n) rarr bits(n)zero-extend ZeroExtend bits(m) rarr bits(n)sign-extend SignExtend bits(m) rarr bits(n)reverse bits Reverse bits(n) rarr bits(n)minimum value (u) Min bits(n)times bits(n) rarr bits(n)maximum value (u) Max bits(n)times bits(n) rarr bits(n)minimum value (s) SignedMin bits(n)times bits(n) rarr bits(n)maximum value (s) SignedMax bits(n)times bits(n) rarr bits(n)widthsize Size bits(n) rarr natmost-significant (sign) bit Msb bits(n) rarr boolbit value middot ltmiddotgt bits(n)times nat rarr boolbit field middot ltmiddotmiddotgt bits(m)times nattimes nat rarr bits(n)concatenation bits(m)times bits(n) rarr bits(p)duplication ^ bits(m)times nat rarr bits(n)less than (s) lt bits(n)times bits(n) rarr boolgreater than (s) gt bits(n)times bits(n) rarr boolless than or equal to (s) lt= bits(n)times bits(n) rarr boolgreater than or equal to (s) gt= bits(n)times bits(n) rarr boolless than (u) lt+ bits(n)times bits(n) rarr boolgreater than (u) gt+ bits(n)times bits(n) rarr boolless than or equal to (u) lt=+ bits(n)times bits(n) rarr boolgreater than or equal to (u) gt=+ bits(n)times bits(n) rarr booladdition + bits(n)times bits(n) rarr bits(n)subtraction - bits(n)times bits(n) rarr bits(n)multiplication bits(n)times bits(n) rarr bits(n)quotient (s) quot bits(n)times bits(n) rarr bits(n)remained (s) rem bits(n)times bits(n) rarr bits(n)division (u) div bits(n)times bits(n) rarr bits(n)modulus (u) mod bits(n)times bits(n) rarr bits(n)division (s) sdiv bits(n)times bits(n) rarr bits(n)modulus (s) smod bits(n)times bits(n) rarr bits(n)bitwise conjunction ampamp bits(n)times bits(n) rarr bits(n)bitwise disjunction || bits(n)times bits(n) rarr bits(n)bitwise exclusive-or bits(n)times bits(n) rarr bits(n)

Unsigned operations are labelled with (u) and signed operations are labelled with (s)The shift operations support shifting by either a bit-vector value or by a natural number value

The overloading is resolved such that the lsquonatrsquo variant is selected over the lsquobits(middot)rsquo version Theshift operations are

24

left-shift ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (u) gtgt+ bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (s) gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate left ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate right gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

A number of operations are undefined depending on the types of their domain and rangeThis is detailed in the following table

Operation Undefined when

ZeroExtend(x`n)`m m lt nSignExtend(x`n)`m m lt n(x`m)ltpgt m le p(x`m)lthlgt`n n = h+ 1minus l or h lt l orm le h((xm) (yn))`p p = m+ n((x`m) ^ n)`p p = m middot n (which covers n = 0)

The type checker will fail when these conditions are obviously violated Alternatively the inter-preter may raise a runtime error when these conditions are not met

As before the expressions lsquoLog2(0)rsquo lsquox quot 0rsquo lsquox rem 0rsquo lsquox div 0rsquo and lsquox mod 0rsquo are allundefined

A6 Bit-stringsVarious bit-string operation are defined over the type lsquobool listrsquo These are listed below

bit value middot ltmiddotgt bool listtimes nat rarr boolbit field middot ltmiddotmiddotgt bool listtimes nattimes nat rarr bool listconcatenation bool listtimes bool list rarr bool listduplication ^ bool listtimes nat rarr bool listaddition + bool listtimes bool list rarr bool listbitwise conjunction ampamp bool listtimes bool list rarr bool listbitwise disjunction || bool listtimes bool list rarr bool listbitwise exclusive-or bool listtimes bool list rarr bool listleft-shift ltlt bool listtimes nat rarr bool listright-shift gtgt+ bool listtimes nat rarr bool listrotate-right gtgt bool listtimes nat rarr bool list

The bit value operation gives the truth value of a bit-string at a given bit position for example

lsquo0s1101lt0gtrsquo = lsquotruersquo lsquo0s1101lt1gtrsquo = lsquofalsersquo lsquo0s1101lt2gtrsquo = lsquotruersquolsquo0s1101lt3gtrsquo = lsquotruersquo lsquo0s1101lt4gtrsquo = lsquofalsersquo lsquo0s1101lt5gtrsquo = lsquofalsersquo

25

The least-significant bit (position zero) occurs to the right of the bit-string The bit value oper-ation gives lsquofalsersquo when the bit position is greater than the size of the bit-string

The bit field operation extracts a range of bits from a bit-string For example

lsquo0s1101lt31gtrsquo = lsquo0s110rsquo and lsquo0s1101lt52gtrsquo = lsquo0s0011rsquo

In the bit-string expression xlthlgt the size of the result is always h + 1 minus l and the result isundefined when h lt l

Bit-string addition does not require the arguments to be of the same size and it gives anon-truncated result For example

lsquo0s101 + 0s1rsquo = lsquo0s110rsquo and lsquo0s101 + 0s11rsquo = lsquo0s1000rsquo

The operation ltlt performs a left-shift for example lsquo0s1101 ltlt 2rsquo = lsquo0s110100rsquo The oper-ation lsquorsquo is bit-string concatenation and lsquo^rsquo is duplication for example

lsquo0s101 0s11rsquo = lsquo0s10111rsquo and lsquo0s101 ^ 3rsquo = lsquo0s101101101rsquo

Regular list operations work as one would expect over bit-strings for example lsquoHead (0s101)rsquois a valid expression with value lsquotruersquo

A7 Characters and StringsThe following built-in functions are available for characters and strings

is alphabetic IsAlpha char rarr boolis alpha-numeric IsAlphaNum char rarr boolis decimal digit IsDigit char rarr boolis hexadecimal digit IsHexDigit char rarr boolis lowercase IsLower char rarr boolis uppercase IsUpper char rarr boolparse binary FromBinString string rarr num optionparse decimal FromDecString string rarr num optionparse hexadecimal FromHexString string rarr num optionconvert to lowercase ToLower string rarr stringconvert to uppercase ToUpper string rarr string

The following string operations are useful for parsing

split from the left splitl (char rarr bool) times string rarr string times stringsplit from the right splitr (char rarr bool) times string rarr string times stringsplit into fields fields (char rarr bool) times string rarr string listsplit into tokens tokens (char rarr bool) times string rarr string list

These are based on the SML functions Substringsplitl Substringsplitr Stringfieldsand Stringtokens Character predicates are declared using special syntax for example theexpression

splitl space or hexdigit and not in set a f ( 12bcab)

gives the result lsquo( 12bc ab)rsquo

26

A8 Floating-pointThe L3 language does not provide specialised types for representing floating-point numbersHowever 32-bit (single precision) and 64-bit (double precision) bit-vector values can be treatedas floating-point numbers the following IEEE compliant encoding formats are assumed

31 30 23 22 0

s e m1 8 23

63 62 52 51 0

s e m1 11 52

Here lsquosrsquo is the sign bit (set to lsquo1rsquo for negative numbers) lsquoersquo is a biased exponent value and lsquomrsquo is thesignificand The following constants and operations are available (where lsquofprsquo stands for bits(32)or bits(64) depending on the name of the operation)

rounding modes roundTiesToEvenroundTowardPositiveroundTowardNegativeroundTowardZero

ieee_rounding

flags (record) DivideByZero InvalidOpOverflow PrecisionUnderflow

ieee_flagsrarrbool

comparison values FP_LT FP_EQ FP_GT FP_UN ieee_compare

convert format FP32_ToFP64 fp32rarrfp64convert format FP64_ToFP32 ieee_roundingtimes fp64rarrfp32convert format FP64_ToFP32_ ieee_roundingtimes fp64rarr

ieee_flagstimes fp32from integer FP32|64_FromInt ieee_roundingtimes intrarrfpto integer FP32|64_ToInt ieee_roundingtimes fprarrint optionfrom string FP32|64 stringrarrfp

negative zero FP32|64_NegZero fppositive zero FP32|64_PosZero fpnegative infinity FP32|64_NegInf fppositive infinity FP32|64_PosInf fpa quiet NaN FP32|64_qNan fpa signalling NaN FP32|64_sNan fp

is integral FP32|64_IsIntegral fprarrboolis finite FP32|64_IsFinite fprarrboolis NaN FP32|64_IsNan fprarrboolis signalling NaN FP32|64_IsSignallingNan fprarrboolis normal FP32|64_IsNormal fprarrboolis sub-normal FP32|64_IsSubnormal fprarrboolis zero FP32|64_IsZero fprarrbool

27

comparison FP32|64_Compare fptimes fprarrieee_compareequality FP32|64_Equal fptimes fprarrboolless than FP32|64_LessThan fptimes fprarrboolless than or equal FP32|64_LessEqual fptimes fprarrboolgreater than FP32|64_GreaterThan fptimes fprarrboolgreater than or equal FP32|64_GreaterEqual fptimes fprarrbool

absolute FP32|64_Abs fprarrfpnegation FP32|64_Neg fprarrfpsquare root FP32|64_Sqrt ieee_roundingtimes fprarrfp(with flags) FP32|64_Sqrt_ ieee_roundingtimes fprarrieee_flagstimes fpaddition FP32|64_Add ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Add_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpsubtraction FP32|64_Sub ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Sub_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpmultiplication FP32|64_Mul ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Mul_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpfused multiply-add FP32|64_MulAdd ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulAdd_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpfused multiply-sub FP32|64_MulSub ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulSub_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpdivision FP32|64_Div ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Div_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fp

The L3 interpreter supports evaluation for 32-bit and 64-bit floating-point expressions but onlywhen running on an x86 machine that supports SSE2 extensions (Pentium 4 and later) Thefused multiply-addsub operations can only be interpreted on machines supporting the FMAextension which came in with the 4th generation (Haswell) Intel processors These restrictionsalso apply to any Standard ML code that is generated by L3

The IEEE 754 standard permits a number of different ways to flag underflow L3 predomi-nantly supports the x86 interpretation which detects underflow after rounding However whenexporting to HOL4 it is possible to choose detection before rounding which for example issuited to ARM instruction set models

A9 Miscellaneous operationsThe following operations are available

pair constructor αtimes β rarr αtimes βfirst of pair Fst αtimes β rarr αsecond of pair Snd αtimes β rarr β

casting [middot] α rarr βinitialise a map InitMap α rarr (βrarrα)

28

option constructor Some αrarrα optionoption projection ValOf α option rarr αoption test IsSome α option rarr bool

set membership in αtimesα set rarr boolset non-membership notin αtimesα set rarr boolset insertion insert αtimesα set rarrα setset union Union α settimesα set rarrα setset intersection Intersect α settimesα set rarrα setset difference Difference α settimesα set rarrα setset subset test IsSubset α settimesα set rarr boolset cardinality Cardinality α setrarr natset from a list SetOfList α list rarrα set

empty list Nil α listlist constructor Cons αtimesα list rarr α listlist head Head α list rarr αlist tail Tail α list rarr α listlist length Length α list rarr natlist concatenation α listtimesα list rarr α listlist flatten Concat α list list rarr α listlist element Element nattimesα list rarr αlist prefix Take nattimesα list rarr α listlist drop prefix Drop nattimesα list rarr α listlist pad left PadLeft αtimes nattimesα list rarr α listlist pad right PadRight αtimes nattimesα list rarr α listlist update Update αtimes nattimesα list rarr α listlist difference Remove α listtimesα list rarr α listlist intersection RemoveExcept α listtimesα list rarr α listlist without duplicates RemoveDuplicates α listrarr α listlist membership IsMember αtimesα list rarr boollist member position IndexOf αtimesα list rarr nat option

Sets are only defined over equality types see Appendix A2 The casting map is defined overcast-able types (as represented by the polymorphic type variables α and β) these are the primitivetypes (with the exception of lsquounitrsquo) and user defined enumerated types Assume lsquoEnumrsquo and lsquoEnum2rsquoare declared with

construct Enum One Two Three construct Enum2 Four Five Six Seven

The cast operations are described in Tables 1 to 7

29

Table 1 Cast to lsquoboolrsquo

From Operation Examples

bool identity lsquo[true]boolrsquo = lsquotruersquostring parse bool lsquo[true]boolrsquo = lsquotruersquo

lsquo[false]boolrsquo = lsquofalsersquootherwise undefined

nat is not zero lsquo[0n3]boolrsquo = lsquotruersquolsquo[0n0]boolrsquo = lsquofalsersquo

int is not zero lsquo[-0i1]boolrsquo = lsquotruersquolsquo[0i0]boolrsquo = lsquofalsersquo

bool list is not zero lsquo[0s11]boolrsquo = lsquotruersquolsquo[0s0]boolrsquo = lsquofalsersquo

bits(middot) is not zero lsquo[3`3]boolrsquo = lsquotruersquolsquo[0`3]boolrsquo = lsquofalsersquo

Enum is not the first element lsquo[One]boolrsquo = lsquofalsersquolsquo[Two]boolrsquo = lsquotruersquo

Table 2 Cast to lsquostringrsquo

From Operation Examples

bool name lsquo[true]stringrsquo = lsquotruersquostring identity lsquo[hello]stringrsquo = lsquohellorsquonat decimal lsquo[0n3]stringrsquo = lsquo3rsquoint signed decimal lsquo[-0i1]stringrsquo = lsquo~1rsquobool list binary lsquo[0s11]stringrsquo = lsquo11rsquobits(middot) unsigned hexadecimal lsquo[139`8]stringrsquo = lsquo8BrsquoEnum name lsquo[One]stringrsquo = lsquoOnersquo

30

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

18 RecordsRecord types can be introduced using the lsquorecordrsquo construct The following is an example of arecord declaration

record rec

number natinteger intboolean bool

Every value of type lsquorecrsquo has three components which may be accessed using dot notation forexample if we have a global variable

declare rec rec

then the sub-elements are lsquorecnumberrsquo lsquorecintegerrsquo and lsquorecbooleanrsquo The language does notprovide a syntax for record literals As such records must be built up incrementally for examplethe following is a sequence of assignments to components of the variable lsquorecrsquo

recnumber lt- 1 recinteger lt- 2 recboolean lt- true

It is not possible to express this with a single assignment to lsquorecrsquo

19 RegistersRegister types can be introduced using the lsquoregisterrsquo construct for example

register sreg bits(32)

31-28 FLAGS7-0 27-16 MODE15-12 MASK

This declares a new type lsquosregrsquo that represents the following 32-bit register31 28 27 16 15 12 11 8 7 0

FLAGS MODElt110gt MASK MODElt1912gt

Note that the bit-field 118 of lsquosregrsquo does not correspond with a named component Also notethat fields are allowed to be non-contiguous which is the case for the lsquoMODErsquo field Register typesare essentially special forms of record types with the automatic specification of bijections toa bit-vector representation Each named bit-field can be accessed using the dot notation forexample if we have

declare status sreg

then the fields lsquostatusFLAGSrsquo and lsquostatusMASKrsquo have type lsquobits(4)rsquo and lsquostatusMODErsquo has typelsquobits(20)rsquo Unlike records register types automatic admit casting tofrom an underlying bit-vector type The expression lsquoampstatusrsquo gives the value of the register (with type lsquobits(32)rsquo) andlsquosreg(0xFFFF0000)rsquo constructs a register of type lsquosregrsquo It is possible to use this notation to updatearbitrary bit-fields of a register for example the statement

ampstatuslt207gt lt- 11101101100111

will update the bit-field 207 of lsquostatusrsquo using the 14-bit literal value

5

110 Polymorphic TypesUsers cannot declare their own polymorphic types Furthermore all user defined operations andvariables must be monomorphic The language does however provide support for three built-inpolymorphic datatypes which may be used under the proviso that these types are always fullytype instantiated (free of type variables)

1101 ListsThe language provides limited support for working with lists Lists can be specified as follows

list 0n0 2 4 -- a list of naturals (length three)0n0 2 3 Nil -- expanded versionCons (0n0 Cons (2 Cons (4 Nil))) -- equivalent version

These expressions have type lsquonat listrsquo Given the first-order nature of L3 only simple listoperations are provided (for example lsquoHeadrsquo lsquoTailrsquo and lsquoLengthrsquo) Higher-order list operationssuch as filter map and fold are not available

1102 Finite SetsThe language provides basic support for finite sets Sets can be specified as follows

set 0n0 2 4 -- a three element set (of naturals)0n0 insert 2 insert 4 insert set -- an expanded versionSetOfList (list 0n0 2 4 ) -- a version built from a list

These expressions have type lsquonat setrsquo The infix operators lsquoinrsquo and lsquonotinrsquo test for set member-ship for example the expressions

0n0 in set 0 2 4 -- test for membership0n1 notin set 0 2 4 -- test for non-membership

both evaluate to lsquotruersquo Sets can only be defined over equality types It is not possible forexample to construct the type lsquo(bool -gt bool) setrsquo

1103 Option TypesThe option type is a polymorphic sum type that has two constructors lsquoNoneα optionrsquo andlsquoSomeαrarrα optionrsquo Option types are helpful when specifying partial operations

111 Statements and ExpressionsThis section presents the statements and expressions of the language Statements can be groupedinto blocks using the syntax

statement1 -- do thisstatement2 -- then do thismiddot middot middot

6

Each block and sub-statement has type lsquounitrsquo The operator lsquorsquo is strictly binary trailing semi-colons not permitted at the end of a sequence of statements Expressions are distinct fromstatements in particular expressions preclude assignments

1111 NothingThe statement lsquonothingrsquo has no effect Its primary purpose is to facilitate the specification ofcontrol flows wherein some paths do something (update the state) and others do nothing8

1112 ConditionalsThe language supports if-then-else statements and expressions and when-do statements Thelatter is provided as a convenient shorthand that is to say the statement

when p do x

is equivalent to the statement

if p then x else nothing

Note that the language does not support layout syntax (the off-side-rule)

1113 For LoopsThe language provides support for simple for-loop statements On each iteration of a for-loopa natural number index variable is either incremented or decremented (by one) This process isrepeated until the index value reaches a pre-computed upper or lower bound for example theloop statements

for i in 1 3 do proc(i)for i in 3 1 do proc(i)

are respectively equivalent to

proc(1) proc(2) proc(3) proc(3) proc(2) proc(1)

The initial and final loop index values may be arbitrary natural number expressions As suchit may be the case that the loop direction will only be known once these bound expressions arecomputed

In addition to regular for loops the language also supports foreach loops which operate overlists For example the following code makes three calls to lsquoprocrsquo

foreach i in list 0n2 4 6 do proc(i)

Note that this construct will also work for bit-strings and for normal stringsThere is no support for do while or repeat until loops

8The lsquonothingrsquo statement is essentially syntactic sugar for lsquo()rsquo

7

1114 Exceptions Unknown and UndefinedThe keyword lsquoUNKNOWNrsquo is used to represent an unspecified element which may be of any giventype The language does not stipulate whether or not this value should be chosen deterministi-cally If the value were chosen deterministically then the expression lsquoUNKNOWN == UNKNOWNrsquo willalways be lsquotruersquo However if the choice is non-deterministic then there is no way of knowing ifan occurrence of this expression is lsquotruersquo or lsquofalsersquo

The language supports user defined exceptions which may be raised but not caught Thelsquoexceptionrsquo keyword is used to declare new exception categories for example

exception ASSERT string

introduces a new exception lsquoASSERTrsquo that takes a single string as an argument This exception canbe raised in expressions and statements as follows

ASSERT (an error has occurred)

Thus exceptions can be used to flag the occurrence of a variety of different errors The L3interpreter will stop when an exception is raised Exceptions can be raised within expressionsand are not constrained by return type

The behaviour of various operations is undefined on some inputs for example the arithmeticexpression lsquox div 0n0rsquo is undefined For any given undefined expression the language permitsthree possible interpretations (implementations)

bull A deterministic value can be chosen For example lsquox div 0n0rsquo is equal to lsquo0n0rsquo is a validinterpretation of this undefined expression

bull A non-deterministic value can be chosen In particular is not necessary for the expressionlsquox div 0n0 == x div 0n0rsquo to be lsquotruersquo

bull An exception can be raised

It is expected that specifications will be designed with some preferred treatment of undefinedbehaviour in mind In this example one possible way to manage undefined cases is by takingcare to explicitly write code of the form lsquoif n == 0 then else x div n rsquo This willensure that undefined cases are unreachable

1115 Procedure CallsA procedure is any user defined operation with return type lsquounitrsquo Procedures typically providefunctionality by means of updating the global state (through side effects) Procedures can becalled (and exceptions can be raised) in statement blocks for example

middot middot middotproc (1 true) -- this is a procedure callmiddot middot middot

The following code is valid but not recommended

8

middot middot middotASSERT error -- raise an exceptionproc (1 true) -- the L3 interpreter will never reach this code

In the above the exception is unconditionally raised so the remaining code should be regardedas unreachable (redundant)

1116 Local VariablesThe L3 language supports two varieties of variables mutable and immutable All global vari-ables are mutable The keyword lsquovarrsquo is used to declare new mutable variables with local scopeLocal variables can be introduced anywhere within a statement block and these variables canbe assigned to using the lsquolt-rsquo operator Immutable variables are introduced within a block usingthe syntax lsquox = expr rsquo and this is treated as a let-statement An immutable value cannot beupdated however it can fall out of scope by declaring a new immutable variable with the samename The operators lsquolt-rsquo and lsquo=rsquo are not permitted in expressions

The specification below uses two mutable variables lsquoxrsquo and lsquoyrsquo

var y = zvar x = yif p then xlt30gt lt- 1111 y lt- x + 1

else xlt74gt lt- 1111 y lt- 0 return (x + y)

This could be respecified using immutable variables for example

y = zx = yx y = if p then (x || 00001111 x || 00001111 + 1)

else (x || 11110000 0)return (x + y)

It is not always easy to eliminate mutable variables In this case the second specification ismore cumbersome because the bit-field update has been replace by an explicit mask (bitwise-or)operation This operations has been repeated in specify the value of lsquoyrsquo because assignments arenot permitted in expressions

Mutable variables can be declared without an initial assignment for example lsquovar xrsquo isequivalent to lsquovar x = UNKNOWNrsquo

1117 PatternMatchingThe language supports match statements and expressions Pattern matching is supported withrespect to literals (see Section 13) constructors9 (immutable) variables wildcards (anonymousvariables) and bit-patterns

9This includes matching on tuples as well as lsquoNonersquo lsquoSomersquo lsquoConsrsquo and lsquoNilrsquo Matching on finite sets and recordfields is not possible

9

Given the type declarations

construct enum One Two Three construct data

NoDataData1 string bits(8)Data2 enum bits(16)

the following illustrates a match expression

match y

case -1 NoData or -2 NoData =gt 0`4 -- note use of orcase _ Data1 (hello 11 x 11) =gt x + 1 -- use of bit-patterncase i Data2 (Three 1111 y) =gt [i] + ylt30gtcase 1 Data2 (_ 8) =gt 4case _ =gt 8

The body (right-hand side of lsquo=gtrsquo) of the first case line with a matching pattern is selected Thesymbol lsquo_rsquo is a wildcard and will match any value The lsquoorrsquo construct provides a shorthand forwriting blocks of clauses with differing patterns but the same body

The terms lsquo11 x 11rsquo and lsquo1111 yrsquo are called bit-patterns and they will match against a setof bit-vector values From the type declaration of lsquodatarsquo it is known that the variable lsquoxrsquo mustrepresent a 4-bit value because it occurs in the middle of an 8-bit word (the match requires bitslsquo11rsquo as a prefix and as a suffix) Likewise lsquoyrsquo must be a 12-bit value Multiple variables can occurin a bit-patterns for example lsquo1 x 1 y 0rsquo is a valid bit-pattern The type checker will oftenbe able to infer the type of pattern variables and if this fails type annotations can be added

The lsquopatternrsquo construct can help avoid situations where explicit annotations are repeatedlyrequired (causing clutter in patterns) If for example the variable lsquoimm5rsquo is frequently used tomatch a 5-bit value then the following declaration can be made

pattern imm5 bits(5)

In subsequent code the default type for pattern variable lsquoimm5rsquo will be lsquobits(5)rsquo The lsquopatternrsquoconstruct only influences type checking If a particular type hint is no longer appropriate thenit can be dropped for example one can insert the declaration lsquoclear pattern imm5rsquo

112 Defining Constants and OperationsUsers can construct operational semantics style formal specifications in L3 by defining their ownconstants and operations There is no module system or facility for local definitions all userdefinitions are made at the top-level with global scope User constants and operations cannot beoverloaded or redefined

A pure constant is a nullary (zero argument) operation that is state independent for examplethe following code declares a new constant

bits(32) UINT_MAX = 0xFFFFFFFF

10

The following code declares operations that are nullary but state dependent

declare number Natnat numberPlus1 = return (number + 1)unit incNumber = number lt- numberPlus1

Users can also declare new unary operations which may or may not be state dependent forexample

nat numberMinusN (nnat) = return (number + n) -- state dependentunit decNumber () = number lt- numberMinusN (1)nat mla (mnatnnatanat) = return (m n + a) -- pure

The operation lsquomlarsquo is unary because it takes a single triple as an argument To enhance clarityand avoid misunderstandards users may elect to specify nullary state dependent operations usinga single lsquounitrsquo argument Given the declarations above the expression lsquodecNumber()rsquo gives theclear impression that a call is being made (with possible side-effects) wheres the expressionlsquoincNumberrsquo does not

At the point of declaration operation arguments must be fully type annotated and onlymonomorphic types are allowed10 It is nevertheless possible to declare bit-vector operationsthat are valid with respect to some given set of bit widths for example the following are validdeclarations

--- valid for any bit-vector width N ---bits(N) bv_mla (mbits(N) nbits(N) abits(N)) = return (m n + a)

--- valid for sufficiently wide bit-vectors (N greater than eight) ---bool bit8 (xbits(N)) with N gt 8 = return (xlt8gt)

An L3 type error will arise if ever an application of the operation lsquobit8rsquo violates the bit widthconstraint Note that vector width variables (such as lsquoNnatrsquo above) can be used as if they werea regular variables in the definitional body of an operation

113 ComponentsWhen specifying instruction set architectures the two most significant programmerrsquos modelcomponents are typically the main memory and a collection of general purpose registers In theMIPS architecture for example there are thirty-two general purpose registers which may berepresented using the following map

declare gpr bits(5) -gt bits(64)

The statement

gpr(d) lt- gpr(r)10An compile time error will arise if the type checker is not able to infer all types the final definition must be

free of type variables

11

then expresses moving a value from register lsquorrsquo to register lsquodrsquo However register a memory accessis frequently more complicated than this in particular registers can be banked and memory canbe complex11 As such it is often necessary to specify collections of operations for accessing(reading and writing) these components With the MIPS example register zero is special (it isa constant value) and so one could define the following operations

bits(64) read_gpr (nbits(5)) = if n == 0 then 0 else gpr (n)unit write_gpr (vbits(64) nbits(5)) = when n ltgt 0 do gpr (n) lt- v

Thus the previous register transfers would now be specified as follows

write_gpr (read_gpr (n) d)

This precise style of specification is not entirely satisfying though since it departs in appearancefrom the pseudo code found in MIPS reference manuals The L3 language provides a specialmechanism for specifying a pair of operations that read and write state components With theMIPS example the following declaration can be made

component GPR (nbits(5)) bits(64)

value = if n == 0 then 0 else gpr(n)assign value = when n ltgt 0 do gpr(n) lt- value

One can then write

GPR(d) lt- GPR(r)

which is closer to the syntax used in the MIPS reference manuals The lsquocomponentrsquo constructeffectively provides a controlled form of operator overloading whereby the lsquoassignrsquo operation12

is select when the operator name appears on the left-hand side of an assignment (lsquolt-rsquo) and thelsquovaluersquo operation13 is applied otherwise Semantically these two operations are exactly the sameas the manually defined versions lsquowrite_gprrsquo and lsquoread_gprrsquo The ldquowriterdquo operation will alwayshave a lsquounitrsquo return type Users are free to specify the ldquoreadrdquo and ldquowriterdquo operations in any mannerthat they deem appropriate however the ldquowriterdquo operation cannot be defined recursively norcan the ldquoreadrdquo operation call the ldquowriterdquo operation

114 RecursionThe language permits the definition of recursive operations It is not possible to define mutuallyrecursive operations

The L3 language has been designed to act as an authoring front-end for the HOL4 theoremprover facilitating the task of writing instruction set specifications In order to successfullyimport an L3 specification it is necessary for the HOL4 system to prove that every user defined

11ARM registers are banked according to processor mode Memory can often be accessed with big- and little-endian byte ordering Special treatment may be needed for unaligned memory addresses for example when readinga 16-bit value from an odd address There may also be address translation (virtualisation) and memory hierarchies(caching)

12In this example the ldquowriterdquo operations is internally called lsquowriteGPRrsquo13Internally the ldquoreadrdquo operation is simply called lsquoGPRrsquo

12

operation is total (terminates on all inputs) If an L3 function is non-terminating then it willbe impossible to export that definition to HOL4 If a function is terminating but the standardautomation of HOL4 is unable to construct a termination proof then it may be necessary toprovide the prover with a hint in the form of a measure

Consider the following specification

declare m bits(8) -gt bits(8)

unit load (abits(8) lbits(8) list) =match l

case Nil =gt nothingcase Cons (h t) =gt m(a) lt- h load (a + 1 t)

The lsquoloadrsquo operation recurses over the list lsquolrsquo loading values into the map lsquomrsquo At the time ofwriting this documentation trying to build the exported HOL4 version of this specificationgives rise to the following error message

Initial goal

existRWF R andforallstate a l h t

(l = ht) rArrR ((a + 1wt)state with m = (a =+ h) statem) ((al)state)

Exception raised at TotalDefnDefinebetween beginning of frag 0 and end of frag 0at TotalDefndefnDefine

Unable to prove termination

Try using TotalDefntDefine ltnamegt ltquotationgt lttacgt

This occurs because HOL4 is unable to automatically prove that lsquoloadrsquo always terminates Toget around this problem the original L3 specification can be modified to contain an annotationas follows

unit load (abits(8) lbits(8) list) measure Length(l) =

The metadata lsquomeasure Length(l)rsquo tells HOL4 to examine the length of the list lsquolrsquo since thisvalue will decrease upon each recursive call to lsquoloadrsquo When the length of the list is zero (thelsquoNilrsquo case) there are no recursive calls so termination is guaranteed

The expression occurring after the lsquomeasurersquo keyword must be of type lsquonatrsquo After provid-ing a measure it is still possible that HOL4 will fail to prove termination either because thesupplied measure is incorrect or because the termination proof is non-trivial (requires humanguidance andor custom lemmas) If this occurs then users should either simplifyrewrite theirspecifications or if necessary report the problem

13

115 Instruction Set DefinitionsWhen working with instruction set models it is helpful to construct a datatype that representsthe set of machine (low-level) instructions This datatype constitutes a simple form of abstractsyntax tree (AST) and it can be used to build instruction decoders (identifying machine-codeinstructions and splitting opcodes into sub-fields) instruction encoders (generating opcodes fora given instruction) next-state functions (applying a semantics function for a given instruction)and assembly code parsers

By way of an example consider the MIPS instruction ANDI this instruction has the assemblycode syntax

ANDI rt rs immediate

and the following 32-bit machine-code encoding

31 26 25 21 20 16 15 0

001100 rs rt immediate6 5 5 16

The semantics of this instruction can be expressed with the operation

unit run_ANDI (rsbits(5) rtbits(5) immbits(16)) =GPR(rt) lt- GPR(rs) ampamp ZeroExtend (imm)

One could use this operation to directly specify a next-state function which would be of theform

unit Next =match Fetch -- fetches a 32-bit opcode from memory

middot middot middotcase 001100 rs rt imm =gt run_ANDI (rs rt imm)middot middot middot

This style of specification is direct and concise however it does lack some of the flexibility thatcomes with using an instruction datatype The L3 language provides support for an slightlydifferent style of specification This alternative approach is explained by first examining howone would specify things manually (explicitly) and then showing how L3 can streamline thisprocess

Firstly one could explicitly define an AST datatype for MIPS instructions it would be ofthe form

construct instruction

middot middot middotANDI bits(5) bits(5) bits(16)middot middot middot

14

This datatype provides a suitable constructor for the ANDI instruction It is now possible to definea decoder which maps opcodes onto AST entries for example

instruction Decode (opcbits(32)) =match opc

middot middot middotcase 001100 rs rt imm =gt ANDI (rs rt imm)middot middot middot

This decoder can be used to define our next-state function that is

unit Next = Run (Decode (Fetch))

where lsquoRunrsquo is defined by

unit Run (iinstruction) =match i

middot middot middotcase ANDI (args) =gt run_ANDI (args)middot middot middot

When working with full-scale architecture specifications (where the AST type is large) thereare some clear overheads associated with implementing this approach (in comparison with theAST free version) It becomes challenging to maintain the AST datatype declaration and tokeep it correctly synchronised with the instruction semantics operations (such as lsquorun_ANDIrsquo)and the definition of lsquoRunrsquo Note however that there is great uniformity in the AST datatypedeclaration and also in the definition of lsquoRunrsquo As such L3 is able to automatically define bothof these for the user

To make use of this automation the declaration of lsquorun_ANDIrsquo is simply modified to

define ANDI (rsbits(5) rtbits(5) immbits(16)) =GPR(rt) lt- GPR(rs) ampamp ZeroExtend (imm)

The lsquodefinersquo keyword tells L3 to define a semantics function14 (as before) and to also create anew lsquoinstructionrsquo datatype AST entry furthermore the two will be linked with the automaticconstruction of a lsquoRunrsquo function The lsquoinstructionrsquo type and lsquoRunrsquo function become defined (inscope) following the declaration lsquodefine Runrsquo After this declaration it is no longer possible touse the lsquodefinersquo construct again however it does become possible to define functions such aslsquoDecodersquo and lsquoNextrsquo

Specifications that are based on using lsquodefinersquo gain the benefits of declaring an instructionAST datatype without the downside of laborious coding overheads In the example above theoverhead amounts to one extra line of code this comes from defining a next-state function thatcalls the dedicated decode function followed by a call to lsquoRunrsquo

One of the key advantages of declaring an instruction datatype is that it makes it consider-ably easier to develop tools that work with assembly code syntax (performing parsing encoding

14This function is internally called lsquodfnANDIrsquo instead of lsquorun_ANDIrsquo

15

and pretty-printing) In this case it is relatively easy for example to map between the MIPSinstruction syntax andi $5 $6 1024 and the expression lsquoANDI (5 6 1024)rsquo Defining anencoder in L3 is relatively straightforward for example

bits(32) Encode (iinstruction) =match i

middot middot middotcase ANDI (rs rt imm) =gt 001100 rs rt immmiddot middot middot

Such a function can be used to write a MIPS assembler which would map the assembly codesyntax andi $5 $6 1024 onto the machine-code value 0x30c50400

2 TutorialThis section gives a brief overview of how to install and use L3

Installation The sources for L3 can be downloaded from the following webpage

wwwclcamacuk~acjf3l3

The file l3tarbz2 can be unpacked with the command

$ tar xvjf l3tarbz2

This will create a directory of the form L3-YYYY-MM-DD where the year month and day willcorrespond with the release date The current version of L3 depends upon PolyML 57 whichcan be obtained from the site polymlorg If PolyML is installed then L3 can be built as follows

$ cd L3-YYYY-MM-DD$ make

Once built the following should appear when you start L315

$ l3ltlt L3 gtgtgt

Users should consider running L3 with the command rlwrap l316

15This assumes that the directory L3-YYYY-MM-DDbin has been added to the PATH environment variable16Details on rlwrap utility can be found at the site freecodecomprojectsrlwrap

16

Basic Interaction The command prompt for L3 is essentially the read-eval-print loop (REPL)of PolyML As such users are free to write arbitrary Standard ML code The structure Runtimeenables interaction with L3 The following shows an arithmetic evaluation in Standard ML aswell as in the L3 interpreter (evalQ)

gt 1 + 2val it = 3 intgt RuntimeevalQ `0i1 + 2`val it = `0i3` Termterm

Various error messages can occur when using the interpreter for example

gt RuntimeevalQ `1 + 2`Exception- Fail Could not infer all types raised

gt RuntimeevalQ `0i2 div 0`Exception- Except (Div SOME (div (int [`0i2` `0i0`]))) raised

The first error occurs because unannotated number literals are regarded as bit-vector values andhere the vector width cannot be inferred

L3 declarations can be made using the function loadQ The following sequence shows thedeclaration and manipulation of a global variable

gt RuntimeloadQ `declare n nat`ltVARgt nval it = () unit

gt RuntimeevalQ `n`val it = `UNKNOWNnat` Termterm

gt RuntimeevalQ ` n lt- 3 n `val it = `0n3` Termterm

The global state can be examined using the function show for example

gt Runtimeshow()val it = [(n `0n3`)] Evalterm_stack

The state can be ldquowipedrdquo clean using the function reset and all declarations can be wiped usinglsquoresetAllrsquo for example

gt Runtimereset()val it = () unitgt Runtimeshow()val it = [(n `UNKNOWNnat`)] Evalterm_stack

gt RuntimeresetAll()val it = () unitgt Runtimeshow()val it = [] Evalterm_stack

The function lsquoLoadQrsquo is similar to lsquoloadQrsquo but it performs a lsquoresetAllrsquo before making declarations

17

Constants The structure Consts provides various functions for working with L3 constantsMany of the operation in the Consts structure will be of little interest to end-users however itcan be used to display some helpful information

The function ConstslookupConst can be used to lookup an operation for example

gt ConstslookupConst Log2val it = Primitive [(bits(a) -gt bits(a) -) (nat -gt nat -)] const

Since lsquoLog2rsquo is a primitive operation only the valid types (ordered by overload priority) are showWith user operations the internal representation (definition) of the operation will be shownfor example

gt RuntimeLoadQ `unit demo () = ()`gt ConstslookupConst demoval it = Definition (Abs ([(_ (unit -))] unit -gt unit `()`) NONE 1)

Constsconst

The functions ConstslistDefinitions and ConstslistExceptions provide details of all useroperations and exceptions respectively The function lsquoConstsstatsrsquo gives a summary of all thecurrent declarations

gt Constsstats()Primitives 188Destructors 5Constructors 0Accessors 0Exceptions 0User operations 1Instruction definitions 0

Here the constructors for primitive types (such as lsquoConsrsquo) are counted under ldquoprimitivesrdquo

Types The Types structure can be used to display information relating to L3 types In partic-ular this structure provides the functions TypeslookupConst and TypeslistConsts which aredemonstrated below

gt RuntimeloadQ `construct enum One Two Three`gt TypeslistConsts()val it =

[(enumeq = true ast = false def = Constructors (Enum ltdict(3)gt) num = 0)]

(string typeconst) list

gt TypeslookupConst intval it = SOME eq = true ast = false def = BaseType num = ~1

typeconst option

18

Loading and Exporting Specifications When writing an L3 specification it is expected thatuser declarations will be contained in an L3 source file A sample instruction set specification(tinyspec) can be found in the L3 distribution subdirectory examples This specification isbased on Thackerrsquos pedagogical Tiny 3 architecture it can be loaded as follows

gt RuntimeLoadF tinyspecLoading tinyspecltTYPgt regTltTYPgt wordTmiddot middot middotltFUNgt test_progDone

The string argument to the functions RuntimeloadF and RuntimeLoadF can be in the form ofa comma separated list of files which will be loaded in order That is the call

RuntimeloadF aspec bspec

will load aspec followed by bspecThe function HolExportexport will export the current L3 specification in the form of an

HOL4 script for example

gt HolExportexport tinyraiseexception okfunction okmiddot middot middotmextend skipmunextend skipCreated file tinyScriptsmlCreated file tinyLibsmlCreated file tinyLibsigDone

The function HolExportspec provides a convenient shortcut for performing LoadF and exportusing just a single call for example HolExportspec (tinyspec tiny) will perform theload and export presented above

L3 is capable of exporting two styles of HOL specification an explicitly monadic version(based on state_transformerTheory) and a version that directly manipulates state using let-expressions (which is the default style) For example a monadic version of the Tiny specifi-cation can be exported using the command HolExportspec (tinyspec tiny monadic)Other export options include sigdocs nosigdocs (for setting HOLrsquos TheoryPPinclude_docstrace variable) bigrecords nobigrecords (for controlling HOLrsquos Datatypebig_record_size)and underflowbefore nounderflowbefore (for selecting the required IEEE 754 underflow be-haviour)

Generated HOL4 specifications are not designed to be manually edited (or human readable)To build an L3 specification script the HOL library Import is needed This library is currentlylocated in the directory $HOL_DIRexamplesl3-machine-codecommon and so adding this path tothe INCLUDES variable of a local Holmakefile is recommended The examplesl3-machine-codedirectory contains various examples of using L3 generated specifications

19

Testing Specifications Having written an L3 specification it is fairly easy to write code (inStandard ML) that runs test vectors Code for running the tinyspec example can be found inthe file run-tinyspec In this test harness the Tiny state is initialised and a small test programis loaded simply by evaluating the expression lsquoinitialize (test_prog)rsquo

It is also possible to evaluate (run) models that have been exported to HOL4 The filerun-tinysml shows how this can be accomplished for the Tiny example

20

A Primitive Types and OperationsThe primitive types are as follows

unit bool char nat int bits(middot) rounding

There are two infix type constructors lsquorsquo for pairs and lsquo-gtrsquo for maps There are also postfix typeconstructors lsquosetrsquo lsquooptionrsquo and lsquolistrsquo for example sets of strings are represented by the typelsquostring setrsquo The following sections describe these primitive types together with some detailsof associated operations The following constants and operations are available

nullary () Nil None false roundTiesToEven roundTowardNegativeroundTowardPositive roundTowardZero true

prefix - ~ Abs Cardinality Cons Difference Drop Element FP32_AbsFP32_Add FP32_Equal FP32_IsNan FP32_LessThan FP32_MulFP32_Neg FP32_Sub FP64_Abs FP64_Add FP64_Equal FP64_IsNanFP64_LessThan FP64_Mul FP64_Neg FP64_Sub FromBinStringFromDecString FromHexString Fst Head IndexOf InitMapIntersection IsAlpha IsAlphaNum IsDigit IsHexDigit IsLowerIsMember IsSome IsSubset IsUpper Length Log2 Max Min MsbQuotRem Remove RemoveDuplicates RemoveExcept ReverseSetOfList SignExtend SignedMax SignedMin Size Snd Some TailTake ToLower ToUpper Union Update ValOf ZeroExtend not

infix = ampamp + - lt lt+ lt= lt=+ ltgt == gt gt+ gt= gt=+ ^ || gtgtltlt gtgt+ ltlt gtgt and div in insert mod notin or quot rem

sdivsmodother middot ltmiddotgt middot ltmiddotmiddotgt [middot] fields splitl splitr tokens

Many arithmetic operations are overloaded Unless otherwise stated the order of selection islsquobits(middot)rsquo lsquonatrsquo lsquointrsquo and then lsquobool listrsquo

A1 UnitThe type lsquounitrsquo represents the singleton set containing the value lsquo()rsquo The primary use of thistype is as the return type for procedures

A2 BoolThe type lsquoboolrsquo represents the two element set B = lsquotruersquo lsquofalsersquo The following standardBoolean operations are available

negation not bool rarr boolconjunction and booltimes bool rarr booldisjunction or booltimes bool rarr boolequality == αtimesα rarr boolnon-equality ltgt = αtimesα rarr bool

21

The infix operators lsquoandrsquo and lsquoorrsquo are interpreted with short-circuit evaluation for example in theexpression lsquofalse and f()rsquo the value of lsquof()rsquo is not computed as the overall expression will alwaysevaluate to false This short-circuiting influences the side-effects that occur during expressionevaluation

There are two prefix symbols for logical negation (these are semantically identical) with lsquorsquobinding slightly tighter than lsquonotrsquo This distinction is becomes significant when working withequalities for example lsquonot a == brsquo is taken to be not(a = b) whereas lsquoa == brsquo is (nota) = b

Equality is only defined with respect to equality types represented here by the type variableα An equality type is any type built without the used of the map operator lsquo-gtrsquo

A3 NatThe type lsquonatrsquo represents the natural numbers N = 0 1 2 The following operations areavailable

logarithm (base two) Log2 nat rarr natminimum value Min nattimes nat rarr natmaximium value Max nattimes nat rarr natless than lt nattimes nat rarr boolgreater than gt nattimes nat rarr boolless than or equal to lt= nattimes nat rarr boolgreater than or equal to gt= nattimes nat rarr booladdition + nattimes nat rarr natsubtraction - nattimes nat rarr natmultiplication nattimes nat rarr natexponentiation nattimes nat rarr natdivision div nattimes nat rarr natmodulus mod nattimes nat rarr nat

The lsquodivrsquo and lsquomodrsquo operations satisfy the following property

foralln 0 lt n =rArr forallk k = (k div n) lowast n+ (k mod n) and (k mod n) lt n

The expressions lsquoLog2(0)rsquo lsquox div 0rsquo and lsquox mod 0rsquo are all undefined 17

A4 IntThe type lsquointrsquo represents the integers Z = Ncupminus1minus2minus3 The following operations areavailable

17The interpreter will raise an exception when attempting to evaluate them

22

unary minus - int rarr intabsolute value Abs int rarr intminimum value Min inttimes int rarr intmaximum value Max inttimes int rarr intless than lt inttimes int rarr boolgreater than gt inttimes int rarr boolless than or equal to lt= inttimes int rarr boolgreater than or equal to gt= inttimes int rarr booladdition + inttimes int rarr intsubtraction - inttimes int rarr intmultiplication inttimes int rarr intexponentiation inttimes nat rarr intquotient and remainder QuotRem inttimes int rarr inttimes intquotient quot inttimes int rarr intremainder rem inttimes int rarr intdivision div inttimes int rarr intmodulus mod inttimes int rarr int

The operation lsquoAbsrsquo gives an positive integer value for example lsquoAbs(-2)rsquo = lsquo2rsquo The integeroperations lsquoquotrsquo and lsquodivrsquo are related to natural number division as follows

i quot j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

and

i div j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(minusi) div n(j))minus 1 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i and n(i) mod n(minusj) = 0

minus z(n(i) div n(minusj))minus 1 j lt 0 and 0 le i and n(i) mod n(minusj) = 0

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

where z NrarrZ and n ZrarrN are value preserving maps The lsquoremrsquo and lsquomodrsquo operations satisfythe equations

i rem j =

iminus (i quot j) lowast j j = 0

undefined j = 0i mod j =

iminus (i div j) lowast j j = 0

undefined j = 0

A5 Bit-vectorsThe type lsquobits(n)rsquo represents fixed-width (n-bit) words also known as bit-vectors for examplebits(32) is the type of 32-bit machine words18 The bits type can be viewed as representing

18These are called double-words (dword) in the x86 architecture and simply words in the ARM architecture

23

the set Zn = 0 1 2nminus1 for some 0 lt n At the type system level no distinction is madebetween signed and unsigned words however some operations (such as orderings) have signedand unsigned variants

The following bit-vector operations are available

1rsquos complement ~ bits(n) rarr bits(n)2rsquos complement - bits(n) rarr bits(n)absolute value Abs bits(n) rarr bits(n)logarithm (base two) Log2 bits(n) rarr bits(n)zero-extend ZeroExtend bits(m) rarr bits(n)sign-extend SignExtend bits(m) rarr bits(n)reverse bits Reverse bits(n) rarr bits(n)minimum value (u) Min bits(n)times bits(n) rarr bits(n)maximum value (u) Max bits(n)times bits(n) rarr bits(n)minimum value (s) SignedMin bits(n)times bits(n) rarr bits(n)maximum value (s) SignedMax bits(n)times bits(n) rarr bits(n)widthsize Size bits(n) rarr natmost-significant (sign) bit Msb bits(n) rarr boolbit value middot ltmiddotgt bits(n)times nat rarr boolbit field middot ltmiddotmiddotgt bits(m)times nattimes nat rarr bits(n)concatenation bits(m)times bits(n) rarr bits(p)duplication ^ bits(m)times nat rarr bits(n)less than (s) lt bits(n)times bits(n) rarr boolgreater than (s) gt bits(n)times bits(n) rarr boolless than or equal to (s) lt= bits(n)times bits(n) rarr boolgreater than or equal to (s) gt= bits(n)times bits(n) rarr boolless than (u) lt+ bits(n)times bits(n) rarr boolgreater than (u) gt+ bits(n)times bits(n) rarr boolless than or equal to (u) lt=+ bits(n)times bits(n) rarr boolgreater than or equal to (u) gt=+ bits(n)times bits(n) rarr booladdition + bits(n)times bits(n) rarr bits(n)subtraction - bits(n)times bits(n) rarr bits(n)multiplication bits(n)times bits(n) rarr bits(n)quotient (s) quot bits(n)times bits(n) rarr bits(n)remained (s) rem bits(n)times bits(n) rarr bits(n)division (u) div bits(n)times bits(n) rarr bits(n)modulus (u) mod bits(n)times bits(n) rarr bits(n)division (s) sdiv bits(n)times bits(n) rarr bits(n)modulus (s) smod bits(n)times bits(n) rarr bits(n)bitwise conjunction ampamp bits(n)times bits(n) rarr bits(n)bitwise disjunction || bits(n)times bits(n) rarr bits(n)bitwise exclusive-or bits(n)times bits(n) rarr bits(n)

Unsigned operations are labelled with (u) and signed operations are labelled with (s)The shift operations support shifting by either a bit-vector value or by a natural number value

The overloading is resolved such that the lsquonatrsquo variant is selected over the lsquobits(middot)rsquo version Theshift operations are

24

left-shift ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (u) gtgt+ bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (s) gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate left ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate right gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

A number of operations are undefined depending on the types of their domain and rangeThis is detailed in the following table

Operation Undefined when

ZeroExtend(x`n)`m m lt nSignExtend(x`n)`m m lt n(x`m)ltpgt m le p(x`m)lthlgt`n n = h+ 1minus l or h lt l orm le h((xm) (yn))`p p = m+ n((x`m) ^ n)`p p = m middot n (which covers n = 0)

The type checker will fail when these conditions are obviously violated Alternatively the inter-preter may raise a runtime error when these conditions are not met

As before the expressions lsquoLog2(0)rsquo lsquox quot 0rsquo lsquox rem 0rsquo lsquox div 0rsquo and lsquox mod 0rsquo are allundefined

A6 Bit-stringsVarious bit-string operation are defined over the type lsquobool listrsquo These are listed below

bit value middot ltmiddotgt bool listtimes nat rarr boolbit field middot ltmiddotmiddotgt bool listtimes nattimes nat rarr bool listconcatenation bool listtimes bool list rarr bool listduplication ^ bool listtimes nat rarr bool listaddition + bool listtimes bool list rarr bool listbitwise conjunction ampamp bool listtimes bool list rarr bool listbitwise disjunction || bool listtimes bool list rarr bool listbitwise exclusive-or bool listtimes bool list rarr bool listleft-shift ltlt bool listtimes nat rarr bool listright-shift gtgt+ bool listtimes nat rarr bool listrotate-right gtgt bool listtimes nat rarr bool list

The bit value operation gives the truth value of a bit-string at a given bit position for example

lsquo0s1101lt0gtrsquo = lsquotruersquo lsquo0s1101lt1gtrsquo = lsquofalsersquo lsquo0s1101lt2gtrsquo = lsquotruersquolsquo0s1101lt3gtrsquo = lsquotruersquo lsquo0s1101lt4gtrsquo = lsquofalsersquo lsquo0s1101lt5gtrsquo = lsquofalsersquo

25

The least-significant bit (position zero) occurs to the right of the bit-string The bit value oper-ation gives lsquofalsersquo when the bit position is greater than the size of the bit-string

The bit field operation extracts a range of bits from a bit-string For example

lsquo0s1101lt31gtrsquo = lsquo0s110rsquo and lsquo0s1101lt52gtrsquo = lsquo0s0011rsquo

In the bit-string expression xlthlgt the size of the result is always h + 1 minus l and the result isundefined when h lt l

Bit-string addition does not require the arguments to be of the same size and it gives anon-truncated result For example

lsquo0s101 + 0s1rsquo = lsquo0s110rsquo and lsquo0s101 + 0s11rsquo = lsquo0s1000rsquo

The operation ltlt performs a left-shift for example lsquo0s1101 ltlt 2rsquo = lsquo0s110100rsquo The oper-ation lsquorsquo is bit-string concatenation and lsquo^rsquo is duplication for example

lsquo0s101 0s11rsquo = lsquo0s10111rsquo and lsquo0s101 ^ 3rsquo = lsquo0s101101101rsquo

Regular list operations work as one would expect over bit-strings for example lsquoHead (0s101)rsquois a valid expression with value lsquotruersquo

A7 Characters and StringsThe following built-in functions are available for characters and strings

is alphabetic IsAlpha char rarr boolis alpha-numeric IsAlphaNum char rarr boolis decimal digit IsDigit char rarr boolis hexadecimal digit IsHexDigit char rarr boolis lowercase IsLower char rarr boolis uppercase IsUpper char rarr boolparse binary FromBinString string rarr num optionparse decimal FromDecString string rarr num optionparse hexadecimal FromHexString string rarr num optionconvert to lowercase ToLower string rarr stringconvert to uppercase ToUpper string rarr string

The following string operations are useful for parsing

split from the left splitl (char rarr bool) times string rarr string times stringsplit from the right splitr (char rarr bool) times string rarr string times stringsplit into fields fields (char rarr bool) times string rarr string listsplit into tokens tokens (char rarr bool) times string rarr string list

These are based on the SML functions Substringsplitl Substringsplitr Stringfieldsand Stringtokens Character predicates are declared using special syntax for example theexpression

splitl space or hexdigit and not in set a f ( 12bcab)

gives the result lsquo( 12bc ab)rsquo

26

A8 Floating-pointThe L3 language does not provide specialised types for representing floating-point numbersHowever 32-bit (single precision) and 64-bit (double precision) bit-vector values can be treatedas floating-point numbers the following IEEE compliant encoding formats are assumed

31 30 23 22 0

s e m1 8 23

63 62 52 51 0

s e m1 11 52

Here lsquosrsquo is the sign bit (set to lsquo1rsquo for negative numbers) lsquoersquo is a biased exponent value and lsquomrsquo is thesignificand The following constants and operations are available (where lsquofprsquo stands for bits(32)or bits(64) depending on the name of the operation)

rounding modes roundTiesToEvenroundTowardPositiveroundTowardNegativeroundTowardZero

ieee_rounding

flags (record) DivideByZero InvalidOpOverflow PrecisionUnderflow

ieee_flagsrarrbool

comparison values FP_LT FP_EQ FP_GT FP_UN ieee_compare

convert format FP32_ToFP64 fp32rarrfp64convert format FP64_ToFP32 ieee_roundingtimes fp64rarrfp32convert format FP64_ToFP32_ ieee_roundingtimes fp64rarr

ieee_flagstimes fp32from integer FP32|64_FromInt ieee_roundingtimes intrarrfpto integer FP32|64_ToInt ieee_roundingtimes fprarrint optionfrom string FP32|64 stringrarrfp

negative zero FP32|64_NegZero fppositive zero FP32|64_PosZero fpnegative infinity FP32|64_NegInf fppositive infinity FP32|64_PosInf fpa quiet NaN FP32|64_qNan fpa signalling NaN FP32|64_sNan fp

is integral FP32|64_IsIntegral fprarrboolis finite FP32|64_IsFinite fprarrboolis NaN FP32|64_IsNan fprarrboolis signalling NaN FP32|64_IsSignallingNan fprarrboolis normal FP32|64_IsNormal fprarrboolis sub-normal FP32|64_IsSubnormal fprarrboolis zero FP32|64_IsZero fprarrbool

27

comparison FP32|64_Compare fptimes fprarrieee_compareequality FP32|64_Equal fptimes fprarrboolless than FP32|64_LessThan fptimes fprarrboolless than or equal FP32|64_LessEqual fptimes fprarrboolgreater than FP32|64_GreaterThan fptimes fprarrboolgreater than or equal FP32|64_GreaterEqual fptimes fprarrbool

absolute FP32|64_Abs fprarrfpnegation FP32|64_Neg fprarrfpsquare root FP32|64_Sqrt ieee_roundingtimes fprarrfp(with flags) FP32|64_Sqrt_ ieee_roundingtimes fprarrieee_flagstimes fpaddition FP32|64_Add ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Add_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpsubtraction FP32|64_Sub ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Sub_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpmultiplication FP32|64_Mul ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Mul_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpfused multiply-add FP32|64_MulAdd ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulAdd_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpfused multiply-sub FP32|64_MulSub ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulSub_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpdivision FP32|64_Div ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Div_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fp

The L3 interpreter supports evaluation for 32-bit and 64-bit floating-point expressions but onlywhen running on an x86 machine that supports SSE2 extensions (Pentium 4 and later) Thefused multiply-addsub operations can only be interpreted on machines supporting the FMAextension which came in with the 4th generation (Haswell) Intel processors These restrictionsalso apply to any Standard ML code that is generated by L3

The IEEE 754 standard permits a number of different ways to flag underflow L3 predomi-nantly supports the x86 interpretation which detects underflow after rounding However whenexporting to HOL4 it is possible to choose detection before rounding which for example issuited to ARM instruction set models

A9 Miscellaneous operationsThe following operations are available

pair constructor αtimes β rarr αtimes βfirst of pair Fst αtimes β rarr αsecond of pair Snd αtimes β rarr β

casting [middot] α rarr βinitialise a map InitMap α rarr (βrarrα)

28

option constructor Some αrarrα optionoption projection ValOf α option rarr αoption test IsSome α option rarr bool

set membership in αtimesα set rarr boolset non-membership notin αtimesα set rarr boolset insertion insert αtimesα set rarrα setset union Union α settimesα set rarrα setset intersection Intersect α settimesα set rarrα setset difference Difference α settimesα set rarrα setset subset test IsSubset α settimesα set rarr boolset cardinality Cardinality α setrarr natset from a list SetOfList α list rarrα set

empty list Nil α listlist constructor Cons αtimesα list rarr α listlist head Head α list rarr αlist tail Tail α list rarr α listlist length Length α list rarr natlist concatenation α listtimesα list rarr α listlist flatten Concat α list list rarr α listlist element Element nattimesα list rarr αlist prefix Take nattimesα list rarr α listlist drop prefix Drop nattimesα list rarr α listlist pad left PadLeft αtimes nattimesα list rarr α listlist pad right PadRight αtimes nattimesα list rarr α listlist update Update αtimes nattimesα list rarr α listlist difference Remove α listtimesα list rarr α listlist intersection RemoveExcept α listtimesα list rarr α listlist without duplicates RemoveDuplicates α listrarr α listlist membership IsMember αtimesα list rarr boollist member position IndexOf αtimesα list rarr nat option

Sets are only defined over equality types see Appendix A2 The casting map is defined overcast-able types (as represented by the polymorphic type variables α and β) these are the primitivetypes (with the exception of lsquounitrsquo) and user defined enumerated types Assume lsquoEnumrsquo and lsquoEnum2rsquoare declared with

construct Enum One Two Three construct Enum2 Four Five Six Seven

The cast operations are described in Tables 1 to 7

29

Table 1 Cast to lsquoboolrsquo

From Operation Examples

bool identity lsquo[true]boolrsquo = lsquotruersquostring parse bool lsquo[true]boolrsquo = lsquotruersquo

lsquo[false]boolrsquo = lsquofalsersquootherwise undefined

nat is not zero lsquo[0n3]boolrsquo = lsquotruersquolsquo[0n0]boolrsquo = lsquofalsersquo

int is not zero lsquo[-0i1]boolrsquo = lsquotruersquolsquo[0i0]boolrsquo = lsquofalsersquo

bool list is not zero lsquo[0s11]boolrsquo = lsquotruersquolsquo[0s0]boolrsquo = lsquofalsersquo

bits(middot) is not zero lsquo[3`3]boolrsquo = lsquotruersquolsquo[0`3]boolrsquo = lsquofalsersquo

Enum is not the first element lsquo[One]boolrsquo = lsquofalsersquolsquo[Two]boolrsquo = lsquotruersquo

Table 2 Cast to lsquostringrsquo

From Operation Examples

bool name lsquo[true]stringrsquo = lsquotruersquostring identity lsquo[hello]stringrsquo = lsquohellorsquonat decimal lsquo[0n3]stringrsquo = lsquo3rsquoint signed decimal lsquo[-0i1]stringrsquo = lsquo~1rsquobool list binary lsquo[0s11]stringrsquo = lsquo11rsquobits(middot) unsigned hexadecimal lsquo[139`8]stringrsquo = lsquo8BrsquoEnum name lsquo[One]stringrsquo = lsquoOnersquo

30

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

110 Polymorphic TypesUsers cannot declare their own polymorphic types Furthermore all user defined operations andvariables must be monomorphic The language does however provide support for three built-inpolymorphic datatypes which may be used under the proviso that these types are always fullytype instantiated (free of type variables)

1101 ListsThe language provides limited support for working with lists Lists can be specified as follows

list 0n0 2 4 -- a list of naturals (length three)0n0 2 3 Nil -- expanded versionCons (0n0 Cons (2 Cons (4 Nil))) -- equivalent version

These expressions have type lsquonat listrsquo Given the first-order nature of L3 only simple listoperations are provided (for example lsquoHeadrsquo lsquoTailrsquo and lsquoLengthrsquo) Higher-order list operationssuch as filter map and fold are not available

1102 Finite SetsThe language provides basic support for finite sets Sets can be specified as follows

set 0n0 2 4 -- a three element set (of naturals)0n0 insert 2 insert 4 insert set -- an expanded versionSetOfList (list 0n0 2 4 ) -- a version built from a list

These expressions have type lsquonat setrsquo The infix operators lsquoinrsquo and lsquonotinrsquo test for set member-ship for example the expressions

0n0 in set 0 2 4 -- test for membership0n1 notin set 0 2 4 -- test for non-membership

both evaluate to lsquotruersquo Sets can only be defined over equality types It is not possible forexample to construct the type lsquo(bool -gt bool) setrsquo

1103 Option TypesThe option type is a polymorphic sum type that has two constructors lsquoNoneα optionrsquo andlsquoSomeαrarrα optionrsquo Option types are helpful when specifying partial operations

111 Statements and ExpressionsThis section presents the statements and expressions of the language Statements can be groupedinto blocks using the syntax

statement1 -- do thisstatement2 -- then do thismiddot middot middot

6

Each block and sub-statement has type lsquounitrsquo The operator lsquorsquo is strictly binary trailing semi-colons not permitted at the end of a sequence of statements Expressions are distinct fromstatements in particular expressions preclude assignments

1111 NothingThe statement lsquonothingrsquo has no effect Its primary purpose is to facilitate the specification ofcontrol flows wherein some paths do something (update the state) and others do nothing8

1112 ConditionalsThe language supports if-then-else statements and expressions and when-do statements Thelatter is provided as a convenient shorthand that is to say the statement

when p do x

is equivalent to the statement

if p then x else nothing

Note that the language does not support layout syntax (the off-side-rule)

1113 For LoopsThe language provides support for simple for-loop statements On each iteration of a for-loopa natural number index variable is either incremented or decremented (by one) This process isrepeated until the index value reaches a pre-computed upper or lower bound for example theloop statements

for i in 1 3 do proc(i)for i in 3 1 do proc(i)

are respectively equivalent to

proc(1) proc(2) proc(3) proc(3) proc(2) proc(1)

The initial and final loop index values may be arbitrary natural number expressions As suchit may be the case that the loop direction will only be known once these bound expressions arecomputed

In addition to regular for loops the language also supports foreach loops which operate overlists For example the following code makes three calls to lsquoprocrsquo

foreach i in list 0n2 4 6 do proc(i)

Note that this construct will also work for bit-strings and for normal stringsThere is no support for do while or repeat until loops

8The lsquonothingrsquo statement is essentially syntactic sugar for lsquo()rsquo

7

1114 Exceptions Unknown and UndefinedThe keyword lsquoUNKNOWNrsquo is used to represent an unspecified element which may be of any giventype The language does not stipulate whether or not this value should be chosen deterministi-cally If the value were chosen deterministically then the expression lsquoUNKNOWN == UNKNOWNrsquo willalways be lsquotruersquo However if the choice is non-deterministic then there is no way of knowing ifan occurrence of this expression is lsquotruersquo or lsquofalsersquo

The language supports user defined exceptions which may be raised but not caught Thelsquoexceptionrsquo keyword is used to declare new exception categories for example

exception ASSERT string

introduces a new exception lsquoASSERTrsquo that takes a single string as an argument This exception canbe raised in expressions and statements as follows

ASSERT (an error has occurred)

Thus exceptions can be used to flag the occurrence of a variety of different errors The L3interpreter will stop when an exception is raised Exceptions can be raised within expressionsand are not constrained by return type

The behaviour of various operations is undefined on some inputs for example the arithmeticexpression lsquox div 0n0rsquo is undefined For any given undefined expression the language permitsthree possible interpretations (implementations)

bull A deterministic value can be chosen For example lsquox div 0n0rsquo is equal to lsquo0n0rsquo is a validinterpretation of this undefined expression

bull A non-deterministic value can be chosen In particular is not necessary for the expressionlsquox div 0n0 == x div 0n0rsquo to be lsquotruersquo

bull An exception can be raised

It is expected that specifications will be designed with some preferred treatment of undefinedbehaviour in mind In this example one possible way to manage undefined cases is by takingcare to explicitly write code of the form lsquoif n == 0 then else x div n rsquo This willensure that undefined cases are unreachable

1115 Procedure CallsA procedure is any user defined operation with return type lsquounitrsquo Procedures typically providefunctionality by means of updating the global state (through side effects) Procedures can becalled (and exceptions can be raised) in statement blocks for example

middot middot middotproc (1 true) -- this is a procedure callmiddot middot middot

The following code is valid but not recommended

8

middot middot middotASSERT error -- raise an exceptionproc (1 true) -- the L3 interpreter will never reach this code

In the above the exception is unconditionally raised so the remaining code should be regardedas unreachable (redundant)

1116 Local VariablesThe L3 language supports two varieties of variables mutable and immutable All global vari-ables are mutable The keyword lsquovarrsquo is used to declare new mutable variables with local scopeLocal variables can be introduced anywhere within a statement block and these variables canbe assigned to using the lsquolt-rsquo operator Immutable variables are introduced within a block usingthe syntax lsquox = expr rsquo and this is treated as a let-statement An immutable value cannot beupdated however it can fall out of scope by declaring a new immutable variable with the samename The operators lsquolt-rsquo and lsquo=rsquo are not permitted in expressions

The specification below uses two mutable variables lsquoxrsquo and lsquoyrsquo

var y = zvar x = yif p then xlt30gt lt- 1111 y lt- x + 1

else xlt74gt lt- 1111 y lt- 0 return (x + y)

This could be respecified using immutable variables for example

y = zx = yx y = if p then (x || 00001111 x || 00001111 + 1)

else (x || 11110000 0)return (x + y)

It is not always easy to eliminate mutable variables In this case the second specification ismore cumbersome because the bit-field update has been replace by an explicit mask (bitwise-or)operation This operations has been repeated in specify the value of lsquoyrsquo because assignments arenot permitted in expressions

Mutable variables can be declared without an initial assignment for example lsquovar xrsquo isequivalent to lsquovar x = UNKNOWNrsquo

1117 PatternMatchingThe language supports match statements and expressions Pattern matching is supported withrespect to literals (see Section 13) constructors9 (immutable) variables wildcards (anonymousvariables) and bit-patterns

9This includes matching on tuples as well as lsquoNonersquo lsquoSomersquo lsquoConsrsquo and lsquoNilrsquo Matching on finite sets and recordfields is not possible

9

Given the type declarations

construct enum One Two Three construct data

NoDataData1 string bits(8)Data2 enum bits(16)

the following illustrates a match expression

match y

case -1 NoData or -2 NoData =gt 0`4 -- note use of orcase _ Data1 (hello 11 x 11) =gt x + 1 -- use of bit-patterncase i Data2 (Three 1111 y) =gt [i] + ylt30gtcase 1 Data2 (_ 8) =gt 4case _ =gt 8

The body (right-hand side of lsquo=gtrsquo) of the first case line with a matching pattern is selected Thesymbol lsquo_rsquo is a wildcard and will match any value The lsquoorrsquo construct provides a shorthand forwriting blocks of clauses with differing patterns but the same body

The terms lsquo11 x 11rsquo and lsquo1111 yrsquo are called bit-patterns and they will match against a setof bit-vector values From the type declaration of lsquodatarsquo it is known that the variable lsquoxrsquo mustrepresent a 4-bit value because it occurs in the middle of an 8-bit word (the match requires bitslsquo11rsquo as a prefix and as a suffix) Likewise lsquoyrsquo must be a 12-bit value Multiple variables can occurin a bit-patterns for example lsquo1 x 1 y 0rsquo is a valid bit-pattern The type checker will oftenbe able to infer the type of pattern variables and if this fails type annotations can be added

The lsquopatternrsquo construct can help avoid situations where explicit annotations are repeatedlyrequired (causing clutter in patterns) If for example the variable lsquoimm5rsquo is frequently used tomatch a 5-bit value then the following declaration can be made

pattern imm5 bits(5)

In subsequent code the default type for pattern variable lsquoimm5rsquo will be lsquobits(5)rsquo The lsquopatternrsquoconstruct only influences type checking If a particular type hint is no longer appropriate thenit can be dropped for example one can insert the declaration lsquoclear pattern imm5rsquo

112 Defining Constants and OperationsUsers can construct operational semantics style formal specifications in L3 by defining their ownconstants and operations There is no module system or facility for local definitions all userdefinitions are made at the top-level with global scope User constants and operations cannot beoverloaded or redefined

A pure constant is a nullary (zero argument) operation that is state independent for examplethe following code declares a new constant

bits(32) UINT_MAX = 0xFFFFFFFF

10

The following code declares operations that are nullary but state dependent

declare number Natnat numberPlus1 = return (number + 1)unit incNumber = number lt- numberPlus1

Users can also declare new unary operations which may or may not be state dependent forexample

nat numberMinusN (nnat) = return (number + n) -- state dependentunit decNumber () = number lt- numberMinusN (1)nat mla (mnatnnatanat) = return (m n + a) -- pure

The operation lsquomlarsquo is unary because it takes a single triple as an argument To enhance clarityand avoid misunderstandards users may elect to specify nullary state dependent operations usinga single lsquounitrsquo argument Given the declarations above the expression lsquodecNumber()rsquo gives theclear impression that a call is being made (with possible side-effects) wheres the expressionlsquoincNumberrsquo does not

At the point of declaration operation arguments must be fully type annotated and onlymonomorphic types are allowed10 It is nevertheless possible to declare bit-vector operationsthat are valid with respect to some given set of bit widths for example the following are validdeclarations

--- valid for any bit-vector width N ---bits(N) bv_mla (mbits(N) nbits(N) abits(N)) = return (m n + a)

--- valid for sufficiently wide bit-vectors (N greater than eight) ---bool bit8 (xbits(N)) with N gt 8 = return (xlt8gt)

An L3 type error will arise if ever an application of the operation lsquobit8rsquo violates the bit widthconstraint Note that vector width variables (such as lsquoNnatrsquo above) can be used as if they werea regular variables in the definitional body of an operation

113 ComponentsWhen specifying instruction set architectures the two most significant programmerrsquos modelcomponents are typically the main memory and a collection of general purpose registers In theMIPS architecture for example there are thirty-two general purpose registers which may berepresented using the following map

declare gpr bits(5) -gt bits(64)

The statement

gpr(d) lt- gpr(r)10An compile time error will arise if the type checker is not able to infer all types the final definition must be

free of type variables

11

then expresses moving a value from register lsquorrsquo to register lsquodrsquo However register a memory accessis frequently more complicated than this in particular registers can be banked and memory canbe complex11 As such it is often necessary to specify collections of operations for accessing(reading and writing) these components With the MIPS example register zero is special (it isa constant value) and so one could define the following operations

bits(64) read_gpr (nbits(5)) = if n == 0 then 0 else gpr (n)unit write_gpr (vbits(64) nbits(5)) = when n ltgt 0 do gpr (n) lt- v

Thus the previous register transfers would now be specified as follows

write_gpr (read_gpr (n) d)

This precise style of specification is not entirely satisfying though since it departs in appearancefrom the pseudo code found in MIPS reference manuals The L3 language provides a specialmechanism for specifying a pair of operations that read and write state components With theMIPS example the following declaration can be made

component GPR (nbits(5)) bits(64)

value = if n == 0 then 0 else gpr(n)assign value = when n ltgt 0 do gpr(n) lt- value

One can then write

GPR(d) lt- GPR(r)

which is closer to the syntax used in the MIPS reference manuals The lsquocomponentrsquo constructeffectively provides a controlled form of operator overloading whereby the lsquoassignrsquo operation12

is select when the operator name appears on the left-hand side of an assignment (lsquolt-rsquo) and thelsquovaluersquo operation13 is applied otherwise Semantically these two operations are exactly the sameas the manually defined versions lsquowrite_gprrsquo and lsquoread_gprrsquo The ldquowriterdquo operation will alwayshave a lsquounitrsquo return type Users are free to specify the ldquoreadrdquo and ldquowriterdquo operations in any mannerthat they deem appropriate however the ldquowriterdquo operation cannot be defined recursively norcan the ldquoreadrdquo operation call the ldquowriterdquo operation

114 RecursionThe language permits the definition of recursive operations It is not possible to define mutuallyrecursive operations

The L3 language has been designed to act as an authoring front-end for the HOL4 theoremprover facilitating the task of writing instruction set specifications In order to successfullyimport an L3 specification it is necessary for the HOL4 system to prove that every user defined

11ARM registers are banked according to processor mode Memory can often be accessed with big- and little-endian byte ordering Special treatment may be needed for unaligned memory addresses for example when readinga 16-bit value from an odd address There may also be address translation (virtualisation) and memory hierarchies(caching)

12In this example the ldquowriterdquo operations is internally called lsquowriteGPRrsquo13Internally the ldquoreadrdquo operation is simply called lsquoGPRrsquo

12

operation is total (terminates on all inputs) If an L3 function is non-terminating then it willbe impossible to export that definition to HOL4 If a function is terminating but the standardautomation of HOL4 is unable to construct a termination proof then it may be necessary toprovide the prover with a hint in the form of a measure

Consider the following specification

declare m bits(8) -gt bits(8)

unit load (abits(8) lbits(8) list) =match l

case Nil =gt nothingcase Cons (h t) =gt m(a) lt- h load (a + 1 t)

The lsquoloadrsquo operation recurses over the list lsquolrsquo loading values into the map lsquomrsquo At the time ofwriting this documentation trying to build the exported HOL4 version of this specificationgives rise to the following error message

Initial goal

existRWF R andforallstate a l h t

(l = ht) rArrR ((a + 1wt)state with m = (a =+ h) statem) ((al)state)

Exception raised at TotalDefnDefinebetween beginning of frag 0 and end of frag 0at TotalDefndefnDefine

Unable to prove termination

Try using TotalDefntDefine ltnamegt ltquotationgt lttacgt

This occurs because HOL4 is unable to automatically prove that lsquoloadrsquo always terminates Toget around this problem the original L3 specification can be modified to contain an annotationas follows

unit load (abits(8) lbits(8) list) measure Length(l) =

The metadata lsquomeasure Length(l)rsquo tells HOL4 to examine the length of the list lsquolrsquo since thisvalue will decrease upon each recursive call to lsquoloadrsquo When the length of the list is zero (thelsquoNilrsquo case) there are no recursive calls so termination is guaranteed

The expression occurring after the lsquomeasurersquo keyword must be of type lsquonatrsquo After provid-ing a measure it is still possible that HOL4 will fail to prove termination either because thesupplied measure is incorrect or because the termination proof is non-trivial (requires humanguidance andor custom lemmas) If this occurs then users should either simplifyrewrite theirspecifications or if necessary report the problem

13

115 Instruction Set DefinitionsWhen working with instruction set models it is helpful to construct a datatype that representsthe set of machine (low-level) instructions This datatype constitutes a simple form of abstractsyntax tree (AST) and it can be used to build instruction decoders (identifying machine-codeinstructions and splitting opcodes into sub-fields) instruction encoders (generating opcodes fora given instruction) next-state functions (applying a semantics function for a given instruction)and assembly code parsers

By way of an example consider the MIPS instruction ANDI this instruction has the assemblycode syntax

ANDI rt rs immediate

and the following 32-bit machine-code encoding

31 26 25 21 20 16 15 0

001100 rs rt immediate6 5 5 16

The semantics of this instruction can be expressed with the operation

unit run_ANDI (rsbits(5) rtbits(5) immbits(16)) =GPR(rt) lt- GPR(rs) ampamp ZeroExtend (imm)

One could use this operation to directly specify a next-state function which would be of theform

unit Next =match Fetch -- fetches a 32-bit opcode from memory

middot middot middotcase 001100 rs rt imm =gt run_ANDI (rs rt imm)middot middot middot

This style of specification is direct and concise however it does lack some of the flexibility thatcomes with using an instruction datatype The L3 language provides support for an slightlydifferent style of specification This alternative approach is explained by first examining howone would specify things manually (explicitly) and then showing how L3 can streamline thisprocess

Firstly one could explicitly define an AST datatype for MIPS instructions it would be ofthe form

construct instruction

middot middot middotANDI bits(5) bits(5) bits(16)middot middot middot

14

This datatype provides a suitable constructor for the ANDI instruction It is now possible to definea decoder which maps opcodes onto AST entries for example

instruction Decode (opcbits(32)) =match opc

middot middot middotcase 001100 rs rt imm =gt ANDI (rs rt imm)middot middot middot

This decoder can be used to define our next-state function that is

unit Next = Run (Decode (Fetch))

where lsquoRunrsquo is defined by

unit Run (iinstruction) =match i

middot middot middotcase ANDI (args) =gt run_ANDI (args)middot middot middot

When working with full-scale architecture specifications (where the AST type is large) thereare some clear overheads associated with implementing this approach (in comparison with theAST free version) It becomes challenging to maintain the AST datatype declaration and tokeep it correctly synchronised with the instruction semantics operations (such as lsquorun_ANDIrsquo)and the definition of lsquoRunrsquo Note however that there is great uniformity in the AST datatypedeclaration and also in the definition of lsquoRunrsquo As such L3 is able to automatically define bothof these for the user

To make use of this automation the declaration of lsquorun_ANDIrsquo is simply modified to

define ANDI (rsbits(5) rtbits(5) immbits(16)) =GPR(rt) lt- GPR(rs) ampamp ZeroExtend (imm)

The lsquodefinersquo keyword tells L3 to define a semantics function14 (as before) and to also create anew lsquoinstructionrsquo datatype AST entry furthermore the two will be linked with the automaticconstruction of a lsquoRunrsquo function The lsquoinstructionrsquo type and lsquoRunrsquo function become defined (inscope) following the declaration lsquodefine Runrsquo After this declaration it is no longer possible touse the lsquodefinersquo construct again however it does become possible to define functions such aslsquoDecodersquo and lsquoNextrsquo

Specifications that are based on using lsquodefinersquo gain the benefits of declaring an instructionAST datatype without the downside of laborious coding overheads In the example above theoverhead amounts to one extra line of code this comes from defining a next-state function thatcalls the dedicated decode function followed by a call to lsquoRunrsquo

One of the key advantages of declaring an instruction datatype is that it makes it consider-ably easier to develop tools that work with assembly code syntax (performing parsing encoding

14This function is internally called lsquodfnANDIrsquo instead of lsquorun_ANDIrsquo

15

and pretty-printing) In this case it is relatively easy for example to map between the MIPSinstruction syntax andi $5 $6 1024 and the expression lsquoANDI (5 6 1024)rsquo Defining anencoder in L3 is relatively straightforward for example

bits(32) Encode (iinstruction) =match i

middot middot middotcase ANDI (rs rt imm) =gt 001100 rs rt immmiddot middot middot

Such a function can be used to write a MIPS assembler which would map the assembly codesyntax andi $5 $6 1024 onto the machine-code value 0x30c50400

2 TutorialThis section gives a brief overview of how to install and use L3

Installation The sources for L3 can be downloaded from the following webpage

wwwclcamacuk~acjf3l3

The file l3tarbz2 can be unpacked with the command

$ tar xvjf l3tarbz2

This will create a directory of the form L3-YYYY-MM-DD where the year month and day willcorrespond with the release date The current version of L3 depends upon PolyML 57 whichcan be obtained from the site polymlorg If PolyML is installed then L3 can be built as follows

$ cd L3-YYYY-MM-DD$ make

Once built the following should appear when you start L315

$ l3ltlt L3 gtgtgt

Users should consider running L3 with the command rlwrap l316

15This assumes that the directory L3-YYYY-MM-DDbin has been added to the PATH environment variable16Details on rlwrap utility can be found at the site freecodecomprojectsrlwrap

16

Basic Interaction The command prompt for L3 is essentially the read-eval-print loop (REPL)of PolyML As such users are free to write arbitrary Standard ML code The structure Runtimeenables interaction with L3 The following shows an arithmetic evaluation in Standard ML aswell as in the L3 interpreter (evalQ)

gt 1 + 2val it = 3 intgt RuntimeevalQ `0i1 + 2`val it = `0i3` Termterm

Various error messages can occur when using the interpreter for example

gt RuntimeevalQ `1 + 2`Exception- Fail Could not infer all types raised

gt RuntimeevalQ `0i2 div 0`Exception- Except (Div SOME (div (int [`0i2` `0i0`]))) raised

The first error occurs because unannotated number literals are regarded as bit-vector values andhere the vector width cannot be inferred

L3 declarations can be made using the function loadQ The following sequence shows thedeclaration and manipulation of a global variable

gt RuntimeloadQ `declare n nat`ltVARgt nval it = () unit

gt RuntimeevalQ `n`val it = `UNKNOWNnat` Termterm

gt RuntimeevalQ ` n lt- 3 n `val it = `0n3` Termterm

The global state can be examined using the function show for example

gt Runtimeshow()val it = [(n `0n3`)] Evalterm_stack

The state can be ldquowipedrdquo clean using the function reset and all declarations can be wiped usinglsquoresetAllrsquo for example

gt Runtimereset()val it = () unitgt Runtimeshow()val it = [(n `UNKNOWNnat`)] Evalterm_stack

gt RuntimeresetAll()val it = () unitgt Runtimeshow()val it = [] Evalterm_stack

The function lsquoLoadQrsquo is similar to lsquoloadQrsquo but it performs a lsquoresetAllrsquo before making declarations

17

Constants The structure Consts provides various functions for working with L3 constantsMany of the operation in the Consts structure will be of little interest to end-users however itcan be used to display some helpful information

The function ConstslookupConst can be used to lookup an operation for example

gt ConstslookupConst Log2val it = Primitive [(bits(a) -gt bits(a) -) (nat -gt nat -)] const

Since lsquoLog2rsquo is a primitive operation only the valid types (ordered by overload priority) are showWith user operations the internal representation (definition) of the operation will be shownfor example

gt RuntimeLoadQ `unit demo () = ()`gt ConstslookupConst demoval it = Definition (Abs ([(_ (unit -))] unit -gt unit `()`) NONE 1)

Constsconst

The functions ConstslistDefinitions and ConstslistExceptions provide details of all useroperations and exceptions respectively The function lsquoConstsstatsrsquo gives a summary of all thecurrent declarations

gt Constsstats()Primitives 188Destructors 5Constructors 0Accessors 0Exceptions 0User operations 1Instruction definitions 0

Here the constructors for primitive types (such as lsquoConsrsquo) are counted under ldquoprimitivesrdquo

Types The Types structure can be used to display information relating to L3 types In partic-ular this structure provides the functions TypeslookupConst and TypeslistConsts which aredemonstrated below

gt RuntimeloadQ `construct enum One Two Three`gt TypeslistConsts()val it =

[(enumeq = true ast = false def = Constructors (Enum ltdict(3)gt) num = 0)]

(string typeconst) list

gt TypeslookupConst intval it = SOME eq = true ast = false def = BaseType num = ~1

typeconst option

18

Loading and Exporting Specifications When writing an L3 specification it is expected thatuser declarations will be contained in an L3 source file A sample instruction set specification(tinyspec) can be found in the L3 distribution subdirectory examples This specification isbased on Thackerrsquos pedagogical Tiny 3 architecture it can be loaded as follows

gt RuntimeLoadF tinyspecLoading tinyspecltTYPgt regTltTYPgt wordTmiddot middot middotltFUNgt test_progDone

The string argument to the functions RuntimeloadF and RuntimeLoadF can be in the form ofa comma separated list of files which will be loaded in order That is the call

RuntimeloadF aspec bspec

will load aspec followed by bspecThe function HolExportexport will export the current L3 specification in the form of an

HOL4 script for example

gt HolExportexport tinyraiseexception okfunction okmiddot middot middotmextend skipmunextend skipCreated file tinyScriptsmlCreated file tinyLibsmlCreated file tinyLibsigDone

The function HolExportspec provides a convenient shortcut for performing LoadF and exportusing just a single call for example HolExportspec (tinyspec tiny) will perform theload and export presented above

L3 is capable of exporting two styles of HOL specification an explicitly monadic version(based on state_transformerTheory) and a version that directly manipulates state using let-expressions (which is the default style) For example a monadic version of the Tiny specifi-cation can be exported using the command HolExportspec (tinyspec tiny monadic)Other export options include sigdocs nosigdocs (for setting HOLrsquos TheoryPPinclude_docstrace variable) bigrecords nobigrecords (for controlling HOLrsquos Datatypebig_record_size)and underflowbefore nounderflowbefore (for selecting the required IEEE 754 underflow be-haviour)

Generated HOL4 specifications are not designed to be manually edited (or human readable)To build an L3 specification script the HOL library Import is needed This library is currentlylocated in the directory $HOL_DIRexamplesl3-machine-codecommon and so adding this path tothe INCLUDES variable of a local Holmakefile is recommended The examplesl3-machine-codedirectory contains various examples of using L3 generated specifications

19

Testing Specifications Having written an L3 specification it is fairly easy to write code (inStandard ML) that runs test vectors Code for running the tinyspec example can be found inthe file run-tinyspec In this test harness the Tiny state is initialised and a small test programis loaded simply by evaluating the expression lsquoinitialize (test_prog)rsquo

It is also possible to evaluate (run) models that have been exported to HOL4 The filerun-tinysml shows how this can be accomplished for the Tiny example

20

A Primitive Types and OperationsThe primitive types are as follows

unit bool char nat int bits(middot) rounding

There are two infix type constructors lsquorsquo for pairs and lsquo-gtrsquo for maps There are also postfix typeconstructors lsquosetrsquo lsquooptionrsquo and lsquolistrsquo for example sets of strings are represented by the typelsquostring setrsquo The following sections describe these primitive types together with some detailsof associated operations The following constants and operations are available

nullary () Nil None false roundTiesToEven roundTowardNegativeroundTowardPositive roundTowardZero true

prefix - ~ Abs Cardinality Cons Difference Drop Element FP32_AbsFP32_Add FP32_Equal FP32_IsNan FP32_LessThan FP32_MulFP32_Neg FP32_Sub FP64_Abs FP64_Add FP64_Equal FP64_IsNanFP64_LessThan FP64_Mul FP64_Neg FP64_Sub FromBinStringFromDecString FromHexString Fst Head IndexOf InitMapIntersection IsAlpha IsAlphaNum IsDigit IsHexDigit IsLowerIsMember IsSome IsSubset IsUpper Length Log2 Max Min MsbQuotRem Remove RemoveDuplicates RemoveExcept ReverseSetOfList SignExtend SignedMax SignedMin Size Snd Some TailTake ToLower ToUpper Union Update ValOf ZeroExtend not

infix = ampamp + - lt lt+ lt= lt=+ ltgt == gt gt+ gt= gt=+ ^ || gtgtltlt gtgt+ ltlt gtgt and div in insert mod notin or quot rem

sdivsmodother middot ltmiddotgt middot ltmiddotmiddotgt [middot] fields splitl splitr tokens

Many arithmetic operations are overloaded Unless otherwise stated the order of selection islsquobits(middot)rsquo lsquonatrsquo lsquointrsquo and then lsquobool listrsquo

A1 UnitThe type lsquounitrsquo represents the singleton set containing the value lsquo()rsquo The primary use of thistype is as the return type for procedures

A2 BoolThe type lsquoboolrsquo represents the two element set B = lsquotruersquo lsquofalsersquo The following standardBoolean operations are available

negation not bool rarr boolconjunction and booltimes bool rarr booldisjunction or booltimes bool rarr boolequality == αtimesα rarr boolnon-equality ltgt = αtimesα rarr bool

21

The infix operators lsquoandrsquo and lsquoorrsquo are interpreted with short-circuit evaluation for example in theexpression lsquofalse and f()rsquo the value of lsquof()rsquo is not computed as the overall expression will alwaysevaluate to false This short-circuiting influences the side-effects that occur during expressionevaluation

There are two prefix symbols for logical negation (these are semantically identical) with lsquorsquobinding slightly tighter than lsquonotrsquo This distinction is becomes significant when working withequalities for example lsquonot a == brsquo is taken to be not(a = b) whereas lsquoa == brsquo is (nota) = b

Equality is only defined with respect to equality types represented here by the type variableα An equality type is any type built without the used of the map operator lsquo-gtrsquo

A3 NatThe type lsquonatrsquo represents the natural numbers N = 0 1 2 The following operations areavailable

logarithm (base two) Log2 nat rarr natminimum value Min nattimes nat rarr natmaximium value Max nattimes nat rarr natless than lt nattimes nat rarr boolgreater than gt nattimes nat rarr boolless than or equal to lt= nattimes nat rarr boolgreater than or equal to gt= nattimes nat rarr booladdition + nattimes nat rarr natsubtraction - nattimes nat rarr natmultiplication nattimes nat rarr natexponentiation nattimes nat rarr natdivision div nattimes nat rarr natmodulus mod nattimes nat rarr nat

The lsquodivrsquo and lsquomodrsquo operations satisfy the following property

foralln 0 lt n =rArr forallk k = (k div n) lowast n+ (k mod n) and (k mod n) lt n

The expressions lsquoLog2(0)rsquo lsquox div 0rsquo and lsquox mod 0rsquo are all undefined 17

A4 IntThe type lsquointrsquo represents the integers Z = Ncupminus1minus2minus3 The following operations areavailable

17The interpreter will raise an exception when attempting to evaluate them

22

unary minus - int rarr intabsolute value Abs int rarr intminimum value Min inttimes int rarr intmaximum value Max inttimes int rarr intless than lt inttimes int rarr boolgreater than gt inttimes int rarr boolless than or equal to lt= inttimes int rarr boolgreater than or equal to gt= inttimes int rarr booladdition + inttimes int rarr intsubtraction - inttimes int rarr intmultiplication inttimes int rarr intexponentiation inttimes nat rarr intquotient and remainder QuotRem inttimes int rarr inttimes intquotient quot inttimes int rarr intremainder rem inttimes int rarr intdivision div inttimes int rarr intmodulus mod inttimes int rarr int

The operation lsquoAbsrsquo gives an positive integer value for example lsquoAbs(-2)rsquo = lsquo2rsquo The integeroperations lsquoquotrsquo and lsquodivrsquo are related to natural number division as follows

i quot j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

and

i div j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(minusi) div n(j))minus 1 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i and n(i) mod n(minusj) = 0

minus z(n(i) div n(minusj))minus 1 j lt 0 and 0 le i and n(i) mod n(minusj) = 0

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

where z NrarrZ and n ZrarrN are value preserving maps The lsquoremrsquo and lsquomodrsquo operations satisfythe equations

i rem j =

iminus (i quot j) lowast j j = 0

undefined j = 0i mod j =

iminus (i div j) lowast j j = 0

undefined j = 0

A5 Bit-vectorsThe type lsquobits(n)rsquo represents fixed-width (n-bit) words also known as bit-vectors for examplebits(32) is the type of 32-bit machine words18 The bits type can be viewed as representing

18These are called double-words (dword) in the x86 architecture and simply words in the ARM architecture

23

the set Zn = 0 1 2nminus1 for some 0 lt n At the type system level no distinction is madebetween signed and unsigned words however some operations (such as orderings) have signedand unsigned variants

The following bit-vector operations are available

1rsquos complement ~ bits(n) rarr bits(n)2rsquos complement - bits(n) rarr bits(n)absolute value Abs bits(n) rarr bits(n)logarithm (base two) Log2 bits(n) rarr bits(n)zero-extend ZeroExtend bits(m) rarr bits(n)sign-extend SignExtend bits(m) rarr bits(n)reverse bits Reverse bits(n) rarr bits(n)minimum value (u) Min bits(n)times bits(n) rarr bits(n)maximum value (u) Max bits(n)times bits(n) rarr bits(n)minimum value (s) SignedMin bits(n)times bits(n) rarr bits(n)maximum value (s) SignedMax bits(n)times bits(n) rarr bits(n)widthsize Size bits(n) rarr natmost-significant (sign) bit Msb bits(n) rarr boolbit value middot ltmiddotgt bits(n)times nat rarr boolbit field middot ltmiddotmiddotgt bits(m)times nattimes nat rarr bits(n)concatenation bits(m)times bits(n) rarr bits(p)duplication ^ bits(m)times nat rarr bits(n)less than (s) lt bits(n)times bits(n) rarr boolgreater than (s) gt bits(n)times bits(n) rarr boolless than or equal to (s) lt= bits(n)times bits(n) rarr boolgreater than or equal to (s) gt= bits(n)times bits(n) rarr boolless than (u) lt+ bits(n)times bits(n) rarr boolgreater than (u) gt+ bits(n)times bits(n) rarr boolless than or equal to (u) lt=+ bits(n)times bits(n) rarr boolgreater than or equal to (u) gt=+ bits(n)times bits(n) rarr booladdition + bits(n)times bits(n) rarr bits(n)subtraction - bits(n)times bits(n) rarr bits(n)multiplication bits(n)times bits(n) rarr bits(n)quotient (s) quot bits(n)times bits(n) rarr bits(n)remained (s) rem bits(n)times bits(n) rarr bits(n)division (u) div bits(n)times bits(n) rarr bits(n)modulus (u) mod bits(n)times bits(n) rarr bits(n)division (s) sdiv bits(n)times bits(n) rarr bits(n)modulus (s) smod bits(n)times bits(n) rarr bits(n)bitwise conjunction ampamp bits(n)times bits(n) rarr bits(n)bitwise disjunction || bits(n)times bits(n) rarr bits(n)bitwise exclusive-or bits(n)times bits(n) rarr bits(n)

Unsigned operations are labelled with (u) and signed operations are labelled with (s)The shift operations support shifting by either a bit-vector value or by a natural number value

The overloading is resolved such that the lsquonatrsquo variant is selected over the lsquobits(middot)rsquo version Theshift operations are

24

left-shift ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (u) gtgt+ bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (s) gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate left ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate right gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

A number of operations are undefined depending on the types of their domain and rangeThis is detailed in the following table

Operation Undefined when

ZeroExtend(x`n)`m m lt nSignExtend(x`n)`m m lt n(x`m)ltpgt m le p(x`m)lthlgt`n n = h+ 1minus l or h lt l orm le h((xm) (yn))`p p = m+ n((x`m) ^ n)`p p = m middot n (which covers n = 0)

The type checker will fail when these conditions are obviously violated Alternatively the inter-preter may raise a runtime error when these conditions are not met

As before the expressions lsquoLog2(0)rsquo lsquox quot 0rsquo lsquox rem 0rsquo lsquox div 0rsquo and lsquox mod 0rsquo are allundefined

A6 Bit-stringsVarious bit-string operation are defined over the type lsquobool listrsquo These are listed below

bit value middot ltmiddotgt bool listtimes nat rarr boolbit field middot ltmiddotmiddotgt bool listtimes nattimes nat rarr bool listconcatenation bool listtimes bool list rarr bool listduplication ^ bool listtimes nat rarr bool listaddition + bool listtimes bool list rarr bool listbitwise conjunction ampamp bool listtimes bool list rarr bool listbitwise disjunction || bool listtimes bool list rarr bool listbitwise exclusive-or bool listtimes bool list rarr bool listleft-shift ltlt bool listtimes nat rarr bool listright-shift gtgt+ bool listtimes nat rarr bool listrotate-right gtgt bool listtimes nat rarr bool list

The bit value operation gives the truth value of a bit-string at a given bit position for example

lsquo0s1101lt0gtrsquo = lsquotruersquo lsquo0s1101lt1gtrsquo = lsquofalsersquo lsquo0s1101lt2gtrsquo = lsquotruersquolsquo0s1101lt3gtrsquo = lsquotruersquo lsquo0s1101lt4gtrsquo = lsquofalsersquo lsquo0s1101lt5gtrsquo = lsquofalsersquo

25

The least-significant bit (position zero) occurs to the right of the bit-string The bit value oper-ation gives lsquofalsersquo when the bit position is greater than the size of the bit-string

The bit field operation extracts a range of bits from a bit-string For example

lsquo0s1101lt31gtrsquo = lsquo0s110rsquo and lsquo0s1101lt52gtrsquo = lsquo0s0011rsquo

In the bit-string expression xlthlgt the size of the result is always h + 1 minus l and the result isundefined when h lt l

Bit-string addition does not require the arguments to be of the same size and it gives anon-truncated result For example

lsquo0s101 + 0s1rsquo = lsquo0s110rsquo and lsquo0s101 + 0s11rsquo = lsquo0s1000rsquo

The operation ltlt performs a left-shift for example lsquo0s1101 ltlt 2rsquo = lsquo0s110100rsquo The oper-ation lsquorsquo is bit-string concatenation and lsquo^rsquo is duplication for example

lsquo0s101 0s11rsquo = lsquo0s10111rsquo and lsquo0s101 ^ 3rsquo = lsquo0s101101101rsquo

Regular list operations work as one would expect over bit-strings for example lsquoHead (0s101)rsquois a valid expression with value lsquotruersquo

A7 Characters and StringsThe following built-in functions are available for characters and strings

is alphabetic IsAlpha char rarr boolis alpha-numeric IsAlphaNum char rarr boolis decimal digit IsDigit char rarr boolis hexadecimal digit IsHexDigit char rarr boolis lowercase IsLower char rarr boolis uppercase IsUpper char rarr boolparse binary FromBinString string rarr num optionparse decimal FromDecString string rarr num optionparse hexadecimal FromHexString string rarr num optionconvert to lowercase ToLower string rarr stringconvert to uppercase ToUpper string rarr string

The following string operations are useful for parsing

split from the left splitl (char rarr bool) times string rarr string times stringsplit from the right splitr (char rarr bool) times string rarr string times stringsplit into fields fields (char rarr bool) times string rarr string listsplit into tokens tokens (char rarr bool) times string rarr string list

These are based on the SML functions Substringsplitl Substringsplitr Stringfieldsand Stringtokens Character predicates are declared using special syntax for example theexpression

splitl space or hexdigit and not in set a f ( 12bcab)

gives the result lsquo( 12bc ab)rsquo

26

A8 Floating-pointThe L3 language does not provide specialised types for representing floating-point numbersHowever 32-bit (single precision) and 64-bit (double precision) bit-vector values can be treatedas floating-point numbers the following IEEE compliant encoding formats are assumed

31 30 23 22 0

s e m1 8 23

63 62 52 51 0

s e m1 11 52

Here lsquosrsquo is the sign bit (set to lsquo1rsquo for negative numbers) lsquoersquo is a biased exponent value and lsquomrsquo is thesignificand The following constants and operations are available (where lsquofprsquo stands for bits(32)or bits(64) depending on the name of the operation)

rounding modes roundTiesToEvenroundTowardPositiveroundTowardNegativeroundTowardZero

ieee_rounding

flags (record) DivideByZero InvalidOpOverflow PrecisionUnderflow

ieee_flagsrarrbool

comparison values FP_LT FP_EQ FP_GT FP_UN ieee_compare

convert format FP32_ToFP64 fp32rarrfp64convert format FP64_ToFP32 ieee_roundingtimes fp64rarrfp32convert format FP64_ToFP32_ ieee_roundingtimes fp64rarr

ieee_flagstimes fp32from integer FP32|64_FromInt ieee_roundingtimes intrarrfpto integer FP32|64_ToInt ieee_roundingtimes fprarrint optionfrom string FP32|64 stringrarrfp

negative zero FP32|64_NegZero fppositive zero FP32|64_PosZero fpnegative infinity FP32|64_NegInf fppositive infinity FP32|64_PosInf fpa quiet NaN FP32|64_qNan fpa signalling NaN FP32|64_sNan fp

is integral FP32|64_IsIntegral fprarrboolis finite FP32|64_IsFinite fprarrboolis NaN FP32|64_IsNan fprarrboolis signalling NaN FP32|64_IsSignallingNan fprarrboolis normal FP32|64_IsNormal fprarrboolis sub-normal FP32|64_IsSubnormal fprarrboolis zero FP32|64_IsZero fprarrbool

27

comparison FP32|64_Compare fptimes fprarrieee_compareequality FP32|64_Equal fptimes fprarrboolless than FP32|64_LessThan fptimes fprarrboolless than or equal FP32|64_LessEqual fptimes fprarrboolgreater than FP32|64_GreaterThan fptimes fprarrboolgreater than or equal FP32|64_GreaterEqual fptimes fprarrbool

absolute FP32|64_Abs fprarrfpnegation FP32|64_Neg fprarrfpsquare root FP32|64_Sqrt ieee_roundingtimes fprarrfp(with flags) FP32|64_Sqrt_ ieee_roundingtimes fprarrieee_flagstimes fpaddition FP32|64_Add ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Add_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpsubtraction FP32|64_Sub ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Sub_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpmultiplication FP32|64_Mul ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Mul_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpfused multiply-add FP32|64_MulAdd ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulAdd_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpfused multiply-sub FP32|64_MulSub ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulSub_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpdivision FP32|64_Div ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Div_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fp

The L3 interpreter supports evaluation for 32-bit and 64-bit floating-point expressions but onlywhen running on an x86 machine that supports SSE2 extensions (Pentium 4 and later) Thefused multiply-addsub operations can only be interpreted on machines supporting the FMAextension which came in with the 4th generation (Haswell) Intel processors These restrictionsalso apply to any Standard ML code that is generated by L3

The IEEE 754 standard permits a number of different ways to flag underflow L3 predomi-nantly supports the x86 interpretation which detects underflow after rounding However whenexporting to HOL4 it is possible to choose detection before rounding which for example issuited to ARM instruction set models

A9 Miscellaneous operationsThe following operations are available

pair constructor αtimes β rarr αtimes βfirst of pair Fst αtimes β rarr αsecond of pair Snd αtimes β rarr β

casting [middot] α rarr βinitialise a map InitMap α rarr (βrarrα)

28

option constructor Some αrarrα optionoption projection ValOf α option rarr αoption test IsSome α option rarr bool

set membership in αtimesα set rarr boolset non-membership notin αtimesα set rarr boolset insertion insert αtimesα set rarrα setset union Union α settimesα set rarrα setset intersection Intersect α settimesα set rarrα setset difference Difference α settimesα set rarrα setset subset test IsSubset α settimesα set rarr boolset cardinality Cardinality α setrarr natset from a list SetOfList α list rarrα set

empty list Nil α listlist constructor Cons αtimesα list rarr α listlist head Head α list rarr αlist tail Tail α list rarr α listlist length Length α list rarr natlist concatenation α listtimesα list rarr α listlist flatten Concat α list list rarr α listlist element Element nattimesα list rarr αlist prefix Take nattimesα list rarr α listlist drop prefix Drop nattimesα list rarr α listlist pad left PadLeft αtimes nattimesα list rarr α listlist pad right PadRight αtimes nattimesα list rarr α listlist update Update αtimes nattimesα list rarr α listlist difference Remove α listtimesα list rarr α listlist intersection RemoveExcept α listtimesα list rarr α listlist without duplicates RemoveDuplicates α listrarr α listlist membership IsMember αtimesα list rarr boollist member position IndexOf αtimesα list rarr nat option

Sets are only defined over equality types see Appendix A2 The casting map is defined overcast-able types (as represented by the polymorphic type variables α and β) these are the primitivetypes (with the exception of lsquounitrsquo) and user defined enumerated types Assume lsquoEnumrsquo and lsquoEnum2rsquoare declared with

construct Enum One Two Three construct Enum2 Four Five Six Seven

The cast operations are described in Tables 1 to 7

29

Table 1 Cast to lsquoboolrsquo

From Operation Examples

bool identity lsquo[true]boolrsquo = lsquotruersquostring parse bool lsquo[true]boolrsquo = lsquotruersquo

lsquo[false]boolrsquo = lsquofalsersquootherwise undefined

nat is not zero lsquo[0n3]boolrsquo = lsquotruersquolsquo[0n0]boolrsquo = lsquofalsersquo

int is not zero lsquo[-0i1]boolrsquo = lsquotruersquolsquo[0i0]boolrsquo = lsquofalsersquo

bool list is not zero lsquo[0s11]boolrsquo = lsquotruersquolsquo[0s0]boolrsquo = lsquofalsersquo

bits(middot) is not zero lsquo[3`3]boolrsquo = lsquotruersquolsquo[0`3]boolrsquo = lsquofalsersquo

Enum is not the first element lsquo[One]boolrsquo = lsquofalsersquolsquo[Two]boolrsquo = lsquotruersquo

Table 2 Cast to lsquostringrsquo

From Operation Examples

bool name lsquo[true]stringrsquo = lsquotruersquostring identity lsquo[hello]stringrsquo = lsquohellorsquonat decimal lsquo[0n3]stringrsquo = lsquo3rsquoint signed decimal lsquo[-0i1]stringrsquo = lsquo~1rsquobool list binary lsquo[0s11]stringrsquo = lsquo11rsquobits(middot) unsigned hexadecimal lsquo[139`8]stringrsquo = lsquo8BrsquoEnum name lsquo[One]stringrsquo = lsquoOnersquo

30

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

Each block and sub-statement has type lsquounitrsquo The operator lsquorsquo is strictly binary trailing semi-colons not permitted at the end of a sequence of statements Expressions are distinct fromstatements in particular expressions preclude assignments

1111 NothingThe statement lsquonothingrsquo has no effect Its primary purpose is to facilitate the specification ofcontrol flows wherein some paths do something (update the state) and others do nothing8

1112 ConditionalsThe language supports if-then-else statements and expressions and when-do statements Thelatter is provided as a convenient shorthand that is to say the statement

when p do x

is equivalent to the statement

if p then x else nothing

Note that the language does not support layout syntax (the off-side-rule)

1113 For LoopsThe language provides support for simple for-loop statements On each iteration of a for-loopa natural number index variable is either incremented or decremented (by one) This process isrepeated until the index value reaches a pre-computed upper or lower bound for example theloop statements

for i in 1 3 do proc(i)for i in 3 1 do proc(i)

are respectively equivalent to

proc(1) proc(2) proc(3) proc(3) proc(2) proc(1)

The initial and final loop index values may be arbitrary natural number expressions As suchit may be the case that the loop direction will only be known once these bound expressions arecomputed

In addition to regular for loops the language also supports foreach loops which operate overlists For example the following code makes three calls to lsquoprocrsquo

foreach i in list 0n2 4 6 do proc(i)

Note that this construct will also work for bit-strings and for normal stringsThere is no support for do while or repeat until loops

8The lsquonothingrsquo statement is essentially syntactic sugar for lsquo()rsquo

7

1114 Exceptions Unknown and UndefinedThe keyword lsquoUNKNOWNrsquo is used to represent an unspecified element which may be of any giventype The language does not stipulate whether or not this value should be chosen deterministi-cally If the value were chosen deterministically then the expression lsquoUNKNOWN == UNKNOWNrsquo willalways be lsquotruersquo However if the choice is non-deterministic then there is no way of knowing ifan occurrence of this expression is lsquotruersquo or lsquofalsersquo

The language supports user defined exceptions which may be raised but not caught Thelsquoexceptionrsquo keyword is used to declare new exception categories for example

exception ASSERT string

introduces a new exception lsquoASSERTrsquo that takes a single string as an argument This exception canbe raised in expressions and statements as follows

ASSERT (an error has occurred)

Thus exceptions can be used to flag the occurrence of a variety of different errors The L3interpreter will stop when an exception is raised Exceptions can be raised within expressionsand are not constrained by return type

The behaviour of various operations is undefined on some inputs for example the arithmeticexpression lsquox div 0n0rsquo is undefined For any given undefined expression the language permitsthree possible interpretations (implementations)

bull A deterministic value can be chosen For example lsquox div 0n0rsquo is equal to lsquo0n0rsquo is a validinterpretation of this undefined expression

bull A non-deterministic value can be chosen In particular is not necessary for the expressionlsquox div 0n0 == x div 0n0rsquo to be lsquotruersquo

bull An exception can be raised

It is expected that specifications will be designed with some preferred treatment of undefinedbehaviour in mind In this example one possible way to manage undefined cases is by takingcare to explicitly write code of the form lsquoif n == 0 then else x div n rsquo This willensure that undefined cases are unreachable

1115 Procedure CallsA procedure is any user defined operation with return type lsquounitrsquo Procedures typically providefunctionality by means of updating the global state (through side effects) Procedures can becalled (and exceptions can be raised) in statement blocks for example

middot middot middotproc (1 true) -- this is a procedure callmiddot middot middot

The following code is valid but not recommended

8

middot middot middotASSERT error -- raise an exceptionproc (1 true) -- the L3 interpreter will never reach this code

In the above the exception is unconditionally raised so the remaining code should be regardedas unreachable (redundant)

1116 Local VariablesThe L3 language supports two varieties of variables mutable and immutable All global vari-ables are mutable The keyword lsquovarrsquo is used to declare new mutable variables with local scopeLocal variables can be introduced anywhere within a statement block and these variables canbe assigned to using the lsquolt-rsquo operator Immutable variables are introduced within a block usingthe syntax lsquox = expr rsquo and this is treated as a let-statement An immutable value cannot beupdated however it can fall out of scope by declaring a new immutable variable with the samename The operators lsquolt-rsquo and lsquo=rsquo are not permitted in expressions

The specification below uses two mutable variables lsquoxrsquo and lsquoyrsquo

var y = zvar x = yif p then xlt30gt lt- 1111 y lt- x + 1

else xlt74gt lt- 1111 y lt- 0 return (x + y)

This could be respecified using immutable variables for example

y = zx = yx y = if p then (x || 00001111 x || 00001111 + 1)

else (x || 11110000 0)return (x + y)

It is not always easy to eliminate mutable variables In this case the second specification ismore cumbersome because the bit-field update has been replace by an explicit mask (bitwise-or)operation This operations has been repeated in specify the value of lsquoyrsquo because assignments arenot permitted in expressions

Mutable variables can be declared without an initial assignment for example lsquovar xrsquo isequivalent to lsquovar x = UNKNOWNrsquo

1117 PatternMatchingThe language supports match statements and expressions Pattern matching is supported withrespect to literals (see Section 13) constructors9 (immutable) variables wildcards (anonymousvariables) and bit-patterns

9This includes matching on tuples as well as lsquoNonersquo lsquoSomersquo lsquoConsrsquo and lsquoNilrsquo Matching on finite sets and recordfields is not possible

9

Given the type declarations

construct enum One Two Three construct data

NoDataData1 string bits(8)Data2 enum bits(16)

the following illustrates a match expression

match y

case -1 NoData or -2 NoData =gt 0`4 -- note use of orcase _ Data1 (hello 11 x 11) =gt x + 1 -- use of bit-patterncase i Data2 (Three 1111 y) =gt [i] + ylt30gtcase 1 Data2 (_ 8) =gt 4case _ =gt 8

The body (right-hand side of lsquo=gtrsquo) of the first case line with a matching pattern is selected Thesymbol lsquo_rsquo is a wildcard and will match any value The lsquoorrsquo construct provides a shorthand forwriting blocks of clauses with differing patterns but the same body

The terms lsquo11 x 11rsquo and lsquo1111 yrsquo are called bit-patterns and they will match against a setof bit-vector values From the type declaration of lsquodatarsquo it is known that the variable lsquoxrsquo mustrepresent a 4-bit value because it occurs in the middle of an 8-bit word (the match requires bitslsquo11rsquo as a prefix and as a suffix) Likewise lsquoyrsquo must be a 12-bit value Multiple variables can occurin a bit-patterns for example lsquo1 x 1 y 0rsquo is a valid bit-pattern The type checker will oftenbe able to infer the type of pattern variables and if this fails type annotations can be added

The lsquopatternrsquo construct can help avoid situations where explicit annotations are repeatedlyrequired (causing clutter in patterns) If for example the variable lsquoimm5rsquo is frequently used tomatch a 5-bit value then the following declaration can be made

pattern imm5 bits(5)

In subsequent code the default type for pattern variable lsquoimm5rsquo will be lsquobits(5)rsquo The lsquopatternrsquoconstruct only influences type checking If a particular type hint is no longer appropriate thenit can be dropped for example one can insert the declaration lsquoclear pattern imm5rsquo

112 Defining Constants and OperationsUsers can construct operational semantics style formal specifications in L3 by defining their ownconstants and operations There is no module system or facility for local definitions all userdefinitions are made at the top-level with global scope User constants and operations cannot beoverloaded or redefined

A pure constant is a nullary (zero argument) operation that is state independent for examplethe following code declares a new constant

bits(32) UINT_MAX = 0xFFFFFFFF

10

The following code declares operations that are nullary but state dependent

declare number Natnat numberPlus1 = return (number + 1)unit incNumber = number lt- numberPlus1

Users can also declare new unary operations which may or may not be state dependent forexample

nat numberMinusN (nnat) = return (number + n) -- state dependentunit decNumber () = number lt- numberMinusN (1)nat mla (mnatnnatanat) = return (m n + a) -- pure

The operation lsquomlarsquo is unary because it takes a single triple as an argument To enhance clarityand avoid misunderstandards users may elect to specify nullary state dependent operations usinga single lsquounitrsquo argument Given the declarations above the expression lsquodecNumber()rsquo gives theclear impression that a call is being made (with possible side-effects) wheres the expressionlsquoincNumberrsquo does not

At the point of declaration operation arguments must be fully type annotated and onlymonomorphic types are allowed10 It is nevertheless possible to declare bit-vector operationsthat are valid with respect to some given set of bit widths for example the following are validdeclarations

--- valid for any bit-vector width N ---bits(N) bv_mla (mbits(N) nbits(N) abits(N)) = return (m n + a)

--- valid for sufficiently wide bit-vectors (N greater than eight) ---bool bit8 (xbits(N)) with N gt 8 = return (xlt8gt)

An L3 type error will arise if ever an application of the operation lsquobit8rsquo violates the bit widthconstraint Note that vector width variables (such as lsquoNnatrsquo above) can be used as if they werea regular variables in the definitional body of an operation

113 ComponentsWhen specifying instruction set architectures the two most significant programmerrsquos modelcomponents are typically the main memory and a collection of general purpose registers In theMIPS architecture for example there are thirty-two general purpose registers which may berepresented using the following map

declare gpr bits(5) -gt bits(64)

The statement

gpr(d) lt- gpr(r)10An compile time error will arise if the type checker is not able to infer all types the final definition must be

free of type variables

11

then expresses moving a value from register lsquorrsquo to register lsquodrsquo However register a memory accessis frequently more complicated than this in particular registers can be banked and memory canbe complex11 As such it is often necessary to specify collections of operations for accessing(reading and writing) these components With the MIPS example register zero is special (it isa constant value) and so one could define the following operations

bits(64) read_gpr (nbits(5)) = if n == 0 then 0 else gpr (n)unit write_gpr (vbits(64) nbits(5)) = when n ltgt 0 do gpr (n) lt- v

Thus the previous register transfers would now be specified as follows

write_gpr (read_gpr (n) d)

This precise style of specification is not entirely satisfying though since it departs in appearancefrom the pseudo code found in MIPS reference manuals The L3 language provides a specialmechanism for specifying a pair of operations that read and write state components With theMIPS example the following declaration can be made

component GPR (nbits(5)) bits(64)

value = if n == 0 then 0 else gpr(n)assign value = when n ltgt 0 do gpr(n) lt- value

One can then write

GPR(d) lt- GPR(r)

which is closer to the syntax used in the MIPS reference manuals The lsquocomponentrsquo constructeffectively provides a controlled form of operator overloading whereby the lsquoassignrsquo operation12

is select when the operator name appears on the left-hand side of an assignment (lsquolt-rsquo) and thelsquovaluersquo operation13 is applied otherwise Semantically these two operations are exactly the sameas the manually defined versions lsquowrite_gprrsquo and lsquoread_gprrsquo The ldquowriterdquo operation will alwayshave a lsquounitrsquo return type Users are free to specify the ldquoreadrdquo and ldquowriterdquo operations in any mannerthat they deem appropriate however the ldquowriterdquo operation cannot be defined recursively norcan the ldquoreadrdquo operation call the ldquowriterdquo operation

114 RecursionThe language permits the definition of recursive operations It is not possible to define mutuallyrecursive operations

The L3 language has been designed to act as an authoring front-end for the HOL4 theoremprover facilitating the task of writing instruction set specifications In order to successfullyimport an L3 specification it is necessary for the HOL4 system to prove that every user defined

11ARM registers are banked according to processor mode Memory can often be accessed with big- and little-endian byte ordering Special treatment may be needed for unaligned memory addresses for example when readinga 16-bit value from an odd address There may also be address translation (virtualisation) and memory hierarchies(caching)

12In this example the ldquowriterdquo operations is internally called lsquowriteGPRrsquo13Internally the ldquoreadrdquo operation is simply called lsquoGPRrsquo

12

operation is total (terminates on all inputs) If an L3 function is non-terminating then it willbe impossible to export that definition to HOL4 If a function is terminating but the standardautomation of HOL4 is unable to construct a termination proof then it may be necessary toprovide the prover with a hint in the form of a measure

Consider the following specification

declare m bits(8) -gt bits(8)

unit load (abits(8) lbits(8) list) =match l

case Nil =gt nothingcase Cons (h t) =gt m(a) lt- h load (a + 1 t)

The lsquoloadrsquo operation recurses over the list lsquolrsquo loading values into the map lsquomrsquo At the time ofwriting this documentation trying to build the exported HOL4 version of this specificationgives rise to the following error message

Initial goal

existRWF R andforallstate a l h t

(l = ht) rArrR ((a + 1wt)state with m = (a =+ h) statem) ((al)state)

Exception raised at TotalDefnDefinebetween beginning of frag 0 and end of frag 0at TotalDefndefnDefine

Unable to prove termination

Try using TotalDefntDefine ltnamegt ltquotationgt lttacgt

This occurs because HOL4 is unable to automatically prove that lsquoloadrsquo always terminates Toget around this problem the original L3 specification can be modified to contain an annotationas follows

unit load (abits(8) lbits(8) list) measure Length(l) =

The metadata lsquomeasure Length(l)rsquo tells HOL4 to examine the length of the list lsquolrsquo since thisvalue will decrease upon each recursive call to lsquoloadrsquo When the length of the list is zero (thelsquoNilrsquo case) there are no recursive calls so termination is guaranteed

The expression occurring after the lsquomeasurersquo keyword must be of type lsquonatrsquo After provid-ing a measure it is still possible that HOL4 will fail to prove termination either because thesupplied measure is incorrect or because the termination proof is non-trivial (requires humanguidance andor custom lemmas) If this occurs then users should either simplifyrewrite theirspecifications or if necessary report the problem

13

115 Instruction Set DefinitionsWhen working with instruction set models it is helpful to construct a datatype that representsthe set of machine (low-level) instructions This datatype constitutes a simple form of abstractsyntax tree (AST) and it can be used to build instruction decoders (identifying machine-codeinstructions and splitting opcodes into sub-fields) instruction encoders (generating opcodes fora given instruction) next-state functions (applying a semantics function for a given instruction)and assembly code parsers

By way of an example consider the MIPS instruction ANDI this instruction has the assemblycode syntax

ANDI rt rs immediate

and the following 32-bit machine-code encoding

31 26 25 21 20 16 15 0

001100 rs rt immediate6 5 5 16

The semantics of this instruction can be expressed with the operation

unit run_ANDI (rsbits(5) rtbits(5) immbits(16)) =GPR(rt) lt- GPR(rs) ampamp ZeroExtend (imm)

One could use this operation to directly specify a next-state function which would be of theform

unit Next =match Fetch -- fetches a 32-bit opcode from memory

middot middot middotcase 001100 rs rt imm =gt run_ANDI (rs rt imm)middot middot middot

This style of specification is direct and concise however it does lack some of the flexibility thatcomes with using an instruction datatype The L3 language provides support for an slightlydifferent style of specification This alternative approach is explained by first examining howone would specify things manually (explicitly) and then showing how L3 can streamline thisprocess

Firstly one could explicitly define an AST datatype for MIPS instructions it would be ofthe form

construct instruction

middot middot middotANDI bits(5) bits(5) bits(16)middot middot middot

14

This datatype provides a suitable constructor for the ANDI instruction It is now possible to definea decoder which maps opcodes onto AST entries for example

instruction Decode (opcbits(32)) =match opc

middot middot middotcase 001100 rs rt imm =gt ANDI (rs rt imm)middot middot middot

This decoder can be used to define our next-state function that is

unit Next = Run (Decode (Fetch))

where lsquoRunrsquo is defined by

unit Run (iinstruction) =match i

middot middot middotcase ANDI (args) =gt run_ANDI (args)middot middot middot

When working with full-scale architecture specifications (where the AST type is large) thereare some clear overheads associated with implementing this approach (in comparison with theAST free version) It becomes challenging to maintain the AST datatype declaration and tokeep it correctly synchronised with the instruction semantics operations (such as lsquorun_ANDIrsquo)and the definition of lsquoRunrsquo Note however that there is great uniformity in the AST datatypedeclaration and also in the definition of lsquoRunrsquo As such L3 is able to automatically define bothof these for the user

To make use of this automation the declaration of lsquorun_ANDIrsquo is simply modified to

define ANDI (rsbits(5) rtbits(5) immbits(16)) =GPR(rt) lt- GPR(rs) ampamp ZeroExtend (imm)

The lsquodefinersquo keyword tells L3 to define a semantics function14 (as before) and to also create anew lsquoinstructionrsquo datatype AST entry furthermore the two will be linked with the automaticconstruction of a lsquoRunrsquo function The lsquoinstructionrsquo type and lsquoRunrsquo function become defined (inscope) following the declaration lsquodefine Runrsquo After this declaration it is no longer possible touse the lsquodefinersquo construct again however it does become possible to define functions such aslsquoDecodersquo and lsquoNextrsquo

Specifications that are based on using lsquodefinersquo gain the benefits of declaring an instructionAST datatype without the downside of laborious coding overheads In the example above theoverhead amounts to one extra line of code this comes from defining a next-state function thatcalls the dedicated decode function followed by a call to lsquoRunrsquo

One of the key advantages of declaring an instruction datatype is that it makes it consider-ably easier to develop tools that work with assembly code syntax (performing parsing encoding

14This function is internally called lsquodfnANDIrsquo instead of lsquorun_ANDIrsquo

15

and pretty-printing) In this case it is relatively easy for example to map between the MIPSinstruction syntax andi $5 $6 1024 and the expression lsquoANDI (5 6 1024)rsquo Defining anencoder in L3 is relatively straightforward for example

bits(32) Encode (iinstruction) =match i

middot middot middotcase ANDI (rs rt imm) =gt 001100 rs rt immmiddot middot middot

Such a function can be used to write a MIPS assembler which would map the assembly codesyntax andi $5 $6 1024 onto the machine-code value 0x30c50400

2 TutorialThis section gives a brief overview of how to install and use L3

Installation The sources for L3 can be downloaded from the following webpage

wwwclcamacuk~acjf3l3

The file l3tarbz2 can be unpacked with the command

$ tar xvjf l3tarbz2

This will create a directory of the form L3-YYYY-MM-DD where the year month and day willcorrespond with the release date The current version of L3 depends upon PolyML 57 whichcan be obtained from the site polymlorg If PolyML is installed then L3 can be built as follows

$ cd L3-YYYY-MM-DD$ make

Once built the following should appear when you start L315

$ l3ltlt L3 gtgtgt

Users should consider running L3 with the command rlwrap l316

15This assumes that the directory L3-YYYY-MM-DDbin has been added to the PATH environment variable16Details on rlwrap utility can be found at the site freecodecomprojectsrlwrap

16

Basic Interaction The command prompt for L3 is essentially the read-eval-print loop (REPL)of PolyML As such users are free to write arbitrary Standard ML code The structure Runtimeenables interaction with L3 The following shows an arithmetic evaluation in Standard ML aswell as in the L3 interpreter (evalQ)

gt 1 + 2val it = 3 intgt RuntimeevalQ `0i1 + 2`val it = `0i3` Termterm

Various error messages can occur when using the interpreter for example

gt RuntimeevalQ `1 + 2`Exception- Fail Could not infer all types raised

gt RuntimeevalQ `0i2 div 0`Exception- Except (Div SOME (div (int [`0i2` `0i0`]))) raised

The first error occurs because unannotated number literals are regarded as bit-vector values andhere the vector width cannot be inferred

L3 declarations can be made using the function loadQ The following sequence shows thedeclaration and manipulation of a global variable

gt RuntimeloadQ `declare n nat`ltVARgt nval it = () unit

gt RuntimeevalQ `n`val it = `UNKNOWNnat` Termterm

gt RuntimeevalQ ` n lt- 3 n `val it = `0n3` Termterm

The global state can be examined using the function show for example

gt Runtimeshow()val it = [(n `0n3`)] Evalterm_stack

The state can be ldquowipedrdquo clean using the function reset and all declarations can be wiped usinglsquoresetAllrsquo for example

gt Runtimereset()val it = () unitgt Runtimeshow()val it = [(n `UNKNOWNnat`)] Evalterm_stack

gt RuntimeresetAll()val it = () unitgt Runtimeshow()val it = [] Evalterm_stack

The function lsquoLoadQrsquo is similar to lsquoloadQrsquo but it performs a lsquoresetAllrsquo before making declarations

17

Constants The structure Consts provides various functions for working with L3 constantsMany of the operation in the Consts structure will be of little interest to end-users however itcan be used to display some helpful information

The function ConstslookupConst can be used to lookup an operation for example

gt ConstslookupConst Log2val it = Primitive [(bits(a) -gt bits(a) -) (nat -gt nat -)] const

Since lsquoLog2rsquo is a primitive operation only the valid types (ordered by overload priority) are showWith user operations the internal representation (definition) of the operation will be shownfor example

gt RuntimeLoadQ `unit demo () = ()`gt ConstslookupConst demoval it = Definition (Abs ([(_ (unit -))] unit -gt unit `()`) NONE 1)

Constsconst

The functions ConstslistDefinitions and ConstslistExceptions provide details of all useroperations and exceptions respectively The function lsquoConstsstatsrsquo gives a summary of all thecurrent declarations

gt Constsstats()Primitives 188Destructors 5Constructors 0Accessors 0Exceptions 0User operations 1Instruction definitions 0

Here the constructors for primitive types (such as lsquoConsrsquo) are counted under ldquoprimitivesrdquo

Types The Types structure can be used to display information relating to L3 types In partic-ular this structure provides the functions TypeslookupConst and TypeslistConsts which aredemonstrated below

gt RuntimeloadQ `construct enum One Two Three`gt TypeslistConsts()val it =

[(enumeq = true ast = false def = Constructors (Enum ltdict(3)gt) num = 0)]

(string typeconst) list

gt TypeslookupConst intval it = SOME eq = true ast = false def = BaseType num = ~1

typeconst option

18

Loading and Exporting Specifications When writing an L3 specification it is expected thatuser declarations will be contained in an L3 source file A sample instruction set specification(tinyspec) can be found in the L3 distribution subdirectory examples This specification isbased on Thackerrsquos pedagogical Tiny 3 architecture it can be loaded as follows

gt RuntimeLoadF tinyspecLoading tinyspecltTYPgt regTltTYPgt wordTmiddot middot middotltFUNgt test_progDone

The string argument to the functions RuntimeloadF and RuntimeLoadF can be in the form ofa comma separated list of files which will be loaded in order That is the call

RuntimeloadF aspec bspec

will load aspec followed by bspecThe function HolExportexport will export the current L3 specification in the form of an

HOL4 script for example

gt HolExportexport tinyraiseexception okfunction okmiddot middot middotmextend skipmunextend skipCreated file tinyScriptsmlCreated file tinyLibsmlCreated file tinyLibsigDone

The function HolExportspec provides a convenient shortcut for performing LoadF and exportusing just a single call for example HolExportspec (tinyspec tiny) will perform theload and export presented above

L3 is capable of exporting two styles of HOL specification an explicitly monadic version(based on state_transformerTheory) and a version that directly manipulates state using let-expressions (which is the default style) For example a monadic version of the Tiny specifi-cation can be exported using the command HolExportspec (tinyspec tiny monadic)Other export options include sigdocs nosigdocs (for setting HOLrsquos TheoryPPinclude_docstrace variable) bigrecords nobigrecords (for controlling HOLrsquos Datatypebig_record_size)and underflowbefore nounderflowbefore (for selecting the required IEEE 754 underflow be-haviour)

Generated HOL4 specifications are not designed to be manually edited (or human readable)To build an L3 specification script the HOL library Import is needed This library is currentlylocated in the directory $HOL_DIRexamplesl3-machine-codecommon and so adding this path tothe INCLUDES variable of a local Holmakefile is recommended The examplesl3-machine-codedirectory contains various examples of using L3 generated specifications

19

Testing Specifications Having written an L3 specification it is fairly easy to write code (inStandard ML) that runs test vectors Code for running the tinyspec example can be found inthe file run-tinyspec In this test harness the Tiny state is initialised and a small test programis loaded simply by evaluating the expression lsquoinitialize (test_prog)rsquo

It is also possible to evaluate (run) models that have been exported to HOL4 The filerun-tinysml shows how this can be accomplished for the Tiny example

20

A Primitive Types and OperationsThe primitive types are as follows

unit bool char nat int bits(middot) rounding

There are two infix type constructors lsquorsquo for pairs and lsquo-gtrsquo for maps There are also postfix typeconstructors lsquosetrsquo lsquooptionrsquo and lsquolistrsquo for example sets of strings are represented by the typelsquostring setrsquo The following sections describe these primitive types together with some detailsof associated operations The following constants and operations are available

nullary () Nil None false roundTiesToEven roundTowardNegativeroundTowardPositive roundTowardZero true

prefix - ~ Abs Cardinality Cons Difference Drop Element FP32_AbsFP32_Add FP32_Equal FP32_IsNan FP32_LessThan FP32_MulFP32_Neg FP32_Sub FP64_Abs FP64_Add FP64_Equal FP64_IsNanFP64_LessThan FP64_Mul FP64_Neg FP64_Sub FromBinStringFromDecString FromHexString Fst Head IndexOf InitMapIntersection IsAlpha IsAlphaNum IsDigit IsHexDigit IsLowerIsMember IsSome IsSubset IsUpper Length Log2 Max Min MsbQuotRem Remove RemoveDuplicates RemoveExcept ReverseSetOfList SignExtend SignedMax SignedMin Size Snd Some TailTake ToLower ToUpper Union Update ValOf ZeroExtend not

infix = ampamp + - lt lt+ lt= lt=+ ltgt == gt gt+ gt= gt=+ ^ || gtgtltlt gtgt+ ltlt gtgt and div in insert mod notin or quot rem

sdivsmodother middot ltmiddotgt middot ltmiddotmiddotgt [middot] fields splitl splitr tokens

Many arithmetic operations are overloaded Unless otherwise stated the order of selection islsquobits(middot)rsquo lsquonatrsquo lsquointrsquo and then lsquobool listrsquo

A1 UnitThe type lsquounitrsquo represents the singleton set containing the value lsquo()rsquo The primary use of thistype is as the return type for procedures

A2 BoolThe type lsquoboolrsquo represents the two element set B = lsquotruersquo lsquofalsersquo The following standardBoolean operations are available

negation not bool rarr boolconjunction and booltimes bool rarr booldisjunction or booltimes bool rarr boolequality == αtimesα rarr boolnon-equality ltgt = αtimesα rarr bool

21

The infix operators lsquoandrsquo and lsquoorrsquo are interpreted with short-circuit evaluation for example in theexpression lsquofalse and f()rsquo the value of lsquof()rsquo is not computed as the overall expression will alwaysevaluate to false This short-circuiting influences the side-effects that occur during expressionevaluation

There are two prefix symbols for logical negation (these are semantically identical) with lsquorsquobinding slightly tighter than lsquonotrsquo This distinction is becomes significant when working withequalities for example lsquonot a == brsquo is taken to be not(a = b) whereas lsquoa == brsquo is (nota) = b

Equality is only defined with respect to equality types represented here by the type variableα An equality type is any type built without the used of the map operator lsquo-gtrsquo

A3 NatThe type lsquonatrsquo represents the natural numbers N = 0 1 2 The following operations areavailable

logarithm (base two) Log2 nat rarr natminimum value Min nattimes nat rarr natmaximium value Max nattimes nat rarr natless than lt nattimes nat rarr boolgreater than gt nattimes nat rarr boolless than or equal to lt= nattimes nat rarr boolgreater than or equal to gt= nattimes nat rarr booladdition + nattimes nat rarr natsubtraction - nattimes nat rarr natmultiplication nattimes nat rarr natexponentiation nattimes nat rarr natdivision div nattimes nat rarr natmodulus mod nattimes nat rarr nat

The lsquodivrsquo and lsquomodrsquo operations satisfy the following property

foralln 0 lt n =rArr forallk k = (k div n) lowast n+ (k mod n) and (k mod n) lt n

The expressions lsquoLog2(0)rsquo lsquox div 0rsquo and lsquox mod 0rsquo are all undefined 17

A4 IntThe type lsquointrsquo represents the integers Z = Ncupminus1minus2minus3 The following operations areavailable

17The interpreter will raise an exception when attempting to evaluate them

22

unary minus - int rarr intabsolute value Abs int rarr intminimum value Min inttimes int rarr intmaximum value Max inttimes int rarr intless than lt inttimes int rarr boolgreater than gt inttimes int rarr boolless than or equal to lt= inttimes int rarr boolgreater than or equal to gt= inttimes int rarr booladdition + inttimes int rarr intsubtraction - inttimes int rarr intmultiplication inttimes int rarr intexponentiation inttimes nat rarr intquotient and remainder QuotRem inttimes int rarr inttimes intquotient quot inttimes int rarr intremainder rem inttimes int rarr intdivision div inttimes int rarr intmodulus mod inttimes int rarr int

The operation lsquoAbsrsquo gives an positive integer value for example lsquoAbs(-2)rsquo = lsquo2rsquo The integeroperations lsquoquotrsquo and lsquodivrsquo are related to natural number division as follows

i quot j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

and

i div j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(minusi) div n(j))minus 1 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i and n(i) mod n(minusj) = 0

minus z(n(i) div n(minusj))minus 1 j lt 0 and 0 le i and n(i) mod n(minusj) = 0

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

where z NrarrZ and n ZrarrN are value preserving maps The lsquoremrsquo and lsquomodrsquo operations satisfythe equations

i rem j =

iminus (i quot j) lowast j j = 0

undefined j = 0i mod j =

iminus (i div j) lowast j j = 0

undefined j = 0

A5 Bit-vectorsThe type lsquobits(n)rsquo represents fixed-width (n-bit) words also known as bit-vectors for examplebits(32) is the type of 32-bit machine words18 The bits type can be viewed as representing

18These are called double-words (dword) in the x86 architecture and simply words in the ARM architecture

23

the set Zn = 0 1 2nminus1 for some 0 lt n At the type system level no distinction is madebetween signed and unsigned words however some operations (such as orderings) have signedand unsigned variants

The following bit-vector operations are available

1rsquos complement ~ bits(n) rarr bits(n)2rsquos complement - bits(n) rarr bits(n)absolute value Abs bits(n) rarr bits(n)logarithm (base two) Log2 bits(n) rarr bits(n)zero-extend ZeroExtend bits(m) rarr bits(n)sign-extend SignExtend bits(m) rarr bits(n)reverse bits Reverse bits(n) rarr bits(n)minimum value (u) Min bits(n)times bits(n) rarr bits(n)maximum value (u) Max bits(n)times bits(n) rarr bits(n)minimum value (s) SignedMin bits(n)times bits(n) rarr bits(n)maximum value (s) SignedMax bits(n)times bits(n) rarr bits(n)widthsize Size bits(n) rarr natmost-significant (sign) bit Msb bits(n) rarr boolbit value middot ltmiddotgt bits(n)times nat rarr boolbit field middot ltmiddotmiddotgt bits(m)times nattimes nat rarr bits(n)concatenation bits(m)times bits(n) rarr bits(p)duplication ^ bits(m)times nat rarr bits(n)less than (s) lt bits(n)times bits(n) rarr boolgreater than (s) gt bits(n)times bits(n) rarr boolless than or equal to (s) lt= bits(n)times bits(n) rarr boolgreater than or equal to (s) gt= bits(n)times bits(n) rarr boolless than (u) lt+ bits(n)times bits(n) rarr boolgreater than (u) gt+ bits(n)times bits(n) rarr boolless than or equal to (u) lt=+ bits(n)times bits(n) rarr boolgreater than or equal to (u) gt=+ bits(n)times bits(n) rarr booladdition + bits(n)times bits(n) rarr bits(n)subtraction - bits(n)times bits(n) rarr bits(n)multiplication bits(n)times bits(n) rarr bits(n)quotient (s) quot bits(n)times bits(n) rarr bits(n)remained (s) rem bits(n)times bits(n) rarr bits(n)division (u) div bits(n)times bits(n) rarr bits(n)modulus (u) mod bits(n)times bits(n) rarr bits(n)division (s) sdiv bits(n)times bits(n) rarr bits(n)modulus (s) smod bits(n)times bits(n) rarr bits(n)bitwise conjunction ampamp bits(n)times bits(n) rarr bits(n)bitwise disjunction || bits(n)times bits(n) rarr bits(n)bitwise exclusive-or bits(n)times bits(n) rarr bits(n)

Unsigned operations are labelled with (u) and signed operations are labelled with (s)The shift operations support shifting by either a bit-vector value or by a natural number value

The overloading is resolved such that the lsquonatrsquo variant is selected over the lsquobits(middot)rsquo version Theshift operations are

24

left-shift ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (u) gtgt+ bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (s) gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate left ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate right gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

A number of operations are undefined depending on the types of their domain and rangeThis is detailed in the following table

Operation Undefined when

ZeroExtend(x`n)`m m lt nSignExtend(x`n)`m m lt n(x`m)ltpgt m le p(x`m)lthlgt`n n = h+ 1minus l or h lt l orm le h((xm) (yn))`p p = m+ n((x`m) ^ n)`p p = m middot n (which covers n = 0)

The type checker will fail when these conditions are obviously violated Alternatively the inter-preter may raise a runtime error when these conditions are not met

As before the expressions lsquoLog2(0)rsquo lsquox quot 0rsquo lsquox rem 0rsquo lsquox div 0rsquo and lsquox mod 0rsquo are allundefined

A6 Bit-stringsVarious bit-string operation are defined over the type lsquobool listrsquo These are listed below

bit value middot ltmiddotgt bool listtimes nat rarr boolbit field middot ltmiddotmiddotgt bool listtimes nattimes nat rarr bool listconcatenation bool listtimes bool list rarr bool listduplication ^ bool listtimes nat rarr bool listaddition + bool listtimes bool list rarr bool listbitwise conjunction ampamp bool listtimes bool list rarr bool listbitwise disjunction || bool listtimes bool list rarr bool listbitwise exclusive-or bool listtimes bool list rarr bool listleft-shift ltlt bool listtimes nat rarr bool listright-shift gtgt+ bool listtimes nat rarr bool listrotate-right gtgt bool listtimes nat rarr bool list

The bit value operation gives the truth value of a bit-string at a given bit position for example

lsquo0s1101lt0gtrsquo = lsquotruersquo lsquo0s1101lt1gtrsquo = lsquofalsersquo lsquo0s1101lt2gtrsquo = lsquotruersquolsquo0s1101lt3gtrsquo = lsquotruersquo lsquo0s1101lt4gtrsquo = lsquofalsersquo lsquo0s1101lt5gtrsquo = lsquofalsersquo

25

The least-significant bit (position zero) occurs to the right of the bit-string The bit value oper-ation gives lsquofalsersquo when the bit position is greater than the size of the bit-string

The bit field operation extracts a range of bits from a bit-string For example

lsquo0s1101lt31gtrsquo = lsquo0s110rsquo and lsquo0s1101lt52gtrsquo = lsquo0s0011rsquo

In the bit-string expression xlthlgt the size of the result is always h + 1 minus l and the result isundefined when h lt l

Bit-string addition does not require the arguments to be of the same size and it gives anon-truncated result For example

lsquo0s101 + 0s1rsquo = lsquo0s110rsquo and lsquo0s101 + 0s11rsquo = lsquo0s1000rsquo

The operation ltlt performs a left-shift for example lsquo0s1101 ltlt 2rsquo = lsquo0s110100rsquo The oper-ation lsquorsquo is bit-string concatenation and lsquo^rsquo is duplication for example

lsquo0s101 0s11rsquo = lsquo0s10111rsquo and lsquo0s101 ^ 3rsquo = lsquo0s101101101rsquo

Regular list operations work as one would expect over bit-strings for example lsquoHead (0s101)rsquois a valid expression with value lsquotruersquo

A7 Characters and StringsThe following built-in functions are available for characters and strings

is alphabetic IsAlpha char rarr boolis alpha-numeric IsAlphaNum char rarr boolis decimal digit IsDigit char rarr boolis hexadecimal digit IsHexDigit char rarr boolis lowercase IsLower char rarr boolis uppercase IsUpper char rarr boolparse binary FromBinString string rarr num optionparse decimal FromDecString string rarr num optionparse hexadecimal FromHexString string rarr num optionconvert to lowercase ToLower string rarr stringconvert to uppercase ToUpper string rarr string

The following string operations are useful for parsing

split from the left splitl (char rarr bool) times string rarr string times stringsplit from the right splitr (char rarr bool) times string rarr string times stringsplit into fields fields (char rarr bool) times string rarr string listsplit into tokens tokens (char rarr bool) times string rarr string list

These are based on the SML functions Substringsplitl Substringsplitr Stringfieldsand Stringtokens Character predicates are declared using special syntax for example theexpression

splitl space or hexdigit and not in set a f ( 12bcab)

gives the result lsquo( 12bc ab)rsquo

26

A8 Floating-pointThe L3 language does not provide specialised types for representing floating-point numbersHowever 32-bit (single precision) and 64-bit (double precision) bit-vector values can be treatedas floating-point numbers the following IEEE compliant encoding formats are assumed

31 30 23 22 0

s e m1 8 23

63 62 52 51 0

s e m1 11 52

Here lsquosrsquo is the sign bit (set to lsquo1rsquo for negative numbers) lsquoersquo is a biased exponent value and lsquomrsquo is thesignificand The following constants and operations are available (where lsquofprsquo stands for bits(32)or bits(64) depending on the name of the operation)

rounding modes roundTiesToEvenroundTowardPositiveroundTowardNegativeroundTowardZero

ieee_rounding

flags (record) DivideByZero InvalidOpOverflow PrecisionUnderflow

ieee_flagsrarrbool

comparison values FP_LT FP_EQ FP_GT FP_UN ieee_compare

convert format FP32_ToFP64 fp32rarrfp64convert format FP64_ToFP32 ieee_roundingtimes fp64rarrfp32convert format FP64_ToFP32_ ieee_roundingtimes fp64rarr

ieee_flagstimes fp32from integer FP32|64_FromInt ieee_roundingtimes intrarrfpto integer FP32|64_ToInt ieee_roundingtimes fprarrint optionfrom string FP32|64 stringrarrfp

negative zero FP32|64_NegZero fppositive zero FP32|64_PosZero fpnegative infinity FP32|64_NegInf fppositive infinity FP32|64_PosInf fpa quiet NaN FP32|64_qNan fpa signalling NaN FP32|64_sNan fp

is integral FP32|64_IsIntegral fprarrboolis finite FP32|64_IsFinite fprarrboolis NaN FP32|64_IsNan fprarrboolis signalling NaN FP32|64_IsSignallingNan fprarrboolis normal FP32|64_IsNormal fprarrboolis sub-normal FP32|64_IsSubnormal fprarrboolis zero FP32|64_IsZero fprarrbool

27

comparison FP32|64_Compare fptimes fprarrieee_compareequality FP32|64_Equal fptimes fprarrboolless than FP32|64_LessThan fptimes fprarrboolless than or equal FP32|64_LessEqual fptimes fprarrboolgreater than FP32|64_GreaterThan fptimes fprarrboolgreater than or equal FP32|64_GreaterEqual fptimes fprarrbool

absolute FP32|64_Abs fprarrfpnegation FP32|64_Neg fprarrfpsquare root FP32|64_Sqrt ieee_roundingtimes fprarrfp(with flags) FP32|64_Sqrt_ ieee_roundingtimes fprarrieee_flagstimes fpaddition FP32|64_Add ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Add_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpsubtraction FP32|64_Sub ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Sub_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpmultiplication FP32|64_Mul ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Mul_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpfused multiply-add FP32|64_MulAdd ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulAdd_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpfused multiply-sub FP32|64_MulSub ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulSub_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpdivision FP32|64_Div ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Div_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fp

The L3 interpreter supports evaluation for 32-bit and 64-bit floating-point expressions but onlywhen running on an x86 machine that supports SSE2 extensions (Pentium 4 and later) Thefused multiply-addsub operations can only be interpreted on machines supporting the FMAextension which came in with the 4th generation (Haswell) Intel processors These restrictionsalso apply to any Standard ML code that is generated by L3

The IEEE 754 standard permits a number of different ways to flag underflow L3 predomi-nantly supports the x86 interpretation which detects underflow after rounding However whenexporting to HOL4 it is possible to choose detection before rounding which for example issuited to ARM instruction set models

A9 Miscellaneous operationsThe following operations are available

pair constructor αtimes β rarr αtimes βfirst of pair Fst αtimes β rarr αsecond of pair Snd αtimes β rarr β

casting [middot] α rarr βinitialise a map InitMap α rarr (βrarrα)

28

option constructor Some αrarrα optionoption projection ValOf α option rarr αoption test IsSome α option rarr bool

set membership in αtimesα set rarr boolset non-membership notin αtimesα set rarr boolset insertion insert αtimesα set rarrα setset union Union α settimesα set rarrα setset intersection Intersect α settimesα set rarrα setset difference Difference α settimesα set rarrα setset subset test IsSubset α settimesα set rarr boolset cardinality Cardinality α setrarr natset from a list SetOfList α list rarrα set

empty list Nil α listlist constructor Cons αtimesα list rarr α listlist head Head α list rarr αlist tail Tail α list rarr α listlist length Length α list rarr natlist concatenation α listtimesα list rarr α listlist flatten Concat α list list rarr α listlist element Element nattimesα list rarr αlist prefix Take nattimesα list rarr α listlist drop prefix Drop nattimesα list rarr α listlist pad left PadLeft αtimes nattimesα list rarr α listlist pad right PadRight αtimes nattimesα list rarr α listlist update Update αtimes nattimesα list rarr α listlist difference Remove α listtimesα list rarr α listlist intersection RemoveExcept α listtimesα list rarr α listlist without duplicates RemoveDuplicates α listrarr α listlist membership IsMember αtimesα list rarr boollist member position IndexOf αtimesα list rarr nat option

Sets are only defined over equality types see Appendix A2 The casting map is defined overcast-able types (as represented by the polymorphic type variables α and β) these are the primitivetypes (with the exception of lsquounitrsquo) and user defined enumerated types Assume lsquoEnumrsquo and lsquoEnum2rsquoare declared with

construct Enum One Two Three construct Enum2 Four Five Six Seven

The cast operations are described in Tables 1 to 7

29

Table 1 Cast to lsquoboolrsquo

From Operation Examples

bool identity lsquo[true]boolrsquo = lsquotruersquostring parse bool lsquo[true]boolrsquo = lsquotruersquo

lsquo[false]boolrsquo = lsquofalsersquootherwise undefined

nat is not zero lsquo[0n3]boolrsquo = lsquotruersquolsquo[0n0]boolrsquo = lsquofalsersquo

int is not zero lsquo[-0i1]boolrsquo = lsquotruersquolsquo[0i0]boolrsquo = lsquofalsersquo

bool list is not zero lsquo[0s11]boolrsquo = lsquotruersquolsquo[0s0]boolrsquo = lsquofalsersquo

bits(middot) is not zero lsquo[3`3]boolrsquo = lsquotruersquolsquo[0`3]boolrsquo = lsquofalsersquo

Enum is not the first element lsquo[One]boolrsquo = lsquofalsersquolsquo[Two]boolrsquo = lsquotruersquo

Table 2 Cast to lsquostringrsquo

From Operation Examples

bool name lsquo[true]stringrsquo = lsquotruersquostring identity lsquo[hello]stringrsquo = lsquohellorsquonat decimal lsquo[0n3]stringrsquo = lsquo3rsquoint signed decimal lsquo[-0i1]stringrsquo = lsquo~1rsquobool list binary lsquo[0s11]stringrsquo = lsquo11rsquobits(middot) unsigned hexadecimal lsquo[139`8]stringrsquo = lsquo8BrsquoEnum name lsquo[One]stringrsquo = lsquoOnersquo

30

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

1114 Exceptions Unknown and UndefinedThe keyword lsquoUNKNOWNrsquo is used to represent an unspecified element which may be of any giventype The language does not stipulate whether or not this value should be chosen deterministi-cally If the value were chosen deterministically then the expression lsquoUNKNOWN == UNKNOWNrsquo willalways be lsquotruersquo However if the choice is non-deterministic then there is no way of knowing ifan occurrence of this expression is lsquotruersquo or lsquofalsersquo

The language supports user defined exceptions which may be raised but not caught Thelsquoexceptionrsquo keyword is used to declare new exception categories for example

exception ASSERT string

introduces a new exception lsquoASSERTrsquo that takes a single string as an argument This exception canbe raised in expressions and statements as follows

ASSERT (an error has occurred)

Thus exceptions can be used to flag the occurrence of a variety of different errors The L3interpreter will stop when an exception is raised Exceptions can be raised within expressionsand are not constrained by return type

The behaviour of various operations is undefined on some inputs for example the arithmeticexpression lsquox div 0n0rsquo is undefined For any given undefined expression the language permitsthree possible interpretations (implementations)

bull A deterministic value can be chosen For example lsquox div 0n0rsquo is equal to lsquo0n0rsquo is a validinterpretation of this undefined expression

bull A non-deterministic value can be chosen In particular is not necessary for the expressionlsquox div 0n0 == x div 0n0rsquo to be lsquotruersquo

bull An exception can be raised

It is expected that specifications will be designed with some preferred treatment of undefinedbehaviour in mind In this example one possible way to manage undefined cases is by takingcare to explicitly write code of the form lsquoif n == 0 then else x div n rsquo This willensure that undefined cases are unreachable

1115 Procedure CallsA procedure is any user defined operation with return type lsquounitrsquo Procedures typically providefunctionality by means of updating the global state (through side effects) Procedures can becalled (and exceptions can be raised) in statement blocks for example

middot middot middotproc (1 true) -- this is a procedure callmiddot middot middot

The following code is valid but not recommended

8

middot middot middotASSERT error -- raise an exceptionproc (1 true) -- the L3 interpreter will never reach this code

In the above the exception is unconditionally raised so the remaining code should be regardedas unreachable (redundant)

1116 Local VariablesThe L3 language supports two varieties of variables mutable and immutable All global vari-ables are mutable The keyword lsquovarrsquo is used to declare new mutable variables with local scopeLocal variables can be introduced anywhere within a statement block and these variables canbe assigned to using the lsquolt-rsquo operator Immutable variables are introduced within a block usingthe syntax lsquox = expr rsquo and this is treated as a let-statement An immutable value cannot beupdated however it can fall out of scope by declaring a new immutable variable with the samename The operators lsquolt-rsquo and lsquo=rsquo are not permitted in expressions

The specification below uses two mutable variables lsquoxrsquo and lsquoyrsquo

var y = zvar x = yif p then xlt30gt lt- 1111 y lt- x + 1

else xlt74gt lt- 1111 y lt- 0 return (x + y)

This could be respecified using immutable variables for example

y = zx = yx y = if p then (x || 00001111 x || 00001111 + 1)

else (x || 11110000 0)return (x + y)

It is not always easy to eliminate mutable variables In this case the second specification ismore cumbersome because the bit-field update has been replace by an explicit mask (bitwise-or)operation This operations has been repeated in specify the value of lsquoyrsquo because assignments arenot permitted in expressions

Mutable variables can be declared without an initial assignment for example lsquovar xrsquo isequivalent to lsquovar x = UNKNOWNrsquo

1117 PatternMatchingThe language supports match statements and expressions Pattern matching is supported withrespect to literals (see Section 13) constructors9 (immutable) variables wildcards (anonymousvariables) and bit-patterns

9This includes matching on tuples as well as lsquoNonersquo lsquoSomersquo lsquoConsrsquo and lsquoNilrsquo Matching on finite sets and recordfields is not possible

9

Given the type declarations

construct enum One Two Three construct data

NoDataData1 string bits(8)Data2 enum bits(16)

the following illustrates a match expression

match y

case -1 NoData or -2 NoData =gt 0`4 -- note use of orcase _ Data1 (hello 11 x 11) =gt x + 1 -- use of bit-patterncase i Data2 (Three 1111 y) =gt [i] + ylt30gtcase 1 Data2 (_ 8) =gt 4case _ =gt 8

The body (right-hand side of lsquo=gtrsquo) of the first case line with a matching pattern is selected Thesymbol lsquo_rsquo is a wildcard and will match any value The lsquoorrsquo construct provides a shorthand forwriting blocks of clauses with differing patterns but the same body

The terms lsquo11 x 11rsquo and lsquo1111 yrsquo are called bit-patterns and they will match against a setof bit-vector values From the type declaration of lsquodatarsquo it is known that the variable lsquoxrsquo mustrepresent a 4-bit value because it occurs in the middle of an 8-bit word (the match requires bitslsquo11rsquo as a prefix and as a suffix) Likewise lsquoyrsquo must be a 12-bit value Multiple variables can occurin a bit-patterns for example lsquo1 x 1 y 0rsquo is a valid bit-pattern The type checker will oftenbe able to infer the type of pattern variables and if this fails type annotations can be added

The lsquopatternrsquo construct can help avoid situations where explicit annotations are repeatedlyrequired (causing clutter in patterns) If for example the variable lsquoimm5rsquo is frequently used tomatch a 5-bit value then the following declaration can be made

pattern imm5 bits(5)

In subsequent code the default type for pattern variable lsquoimm5rsquo will be lsquobits(5)rsquo The lsquopatternrsquoconstruct only influences type checking If a particular type hint is no longer appropriate thenit can be dropped for example one can insert the declaration lsquoclear pattern imm5rsquo

112 Defining Constants and OperationsUsers can construct operational semantics style formal specifications in L3 by defining their ownconstants and operations There is no module system or facility for local definitions all userdefinitions are made at the top-level with global scope User constants and operations cannot beoverloaded or redefined

A pure constant is a nullary (zero argument) operation that is state independent for examplethe following code declares a new constant

bits(32) UINT_MAX = 0xFFFFFFFF

10

The following code declares operations that are nullary but state dependent

declare number Natnat numberPlus1 = return (number + 1)unit incNumber = number lt- numberPlus1

Users can also declare new unary operations which may or may not be state dependent forexample

nat numberMinusN (nnat) = return (number + n) -- state dependentunit decNumber () = number lt- numberMinusN (1)nat mla (mnatnnatanat) = return (m n + a) -- pure

The operation lsquomlarsquo is unary because it takes a single triple as an argument To enhance clarityand avoid misunderstandards users may elect to specify nullary state dependent operations usinga single lsquounitrsquo argument Given the declarations above the expression lsquodecNumber()rsquo gives theclear impression that a call is being made (with possible side-effects) wheres the expressionlsquoincNumberrsquo does not

At the point of declaration operation arguments must be fully type annotated and onlymonomorphic types are allowed10 It is nevertheless possible to declare bit-vector operationsthat are valid with respect to some given set of bit widths for example the following are validdeclarations

--- valid for any bit-vector width N ---bits(N) bv_mla (mbits(N) nbits(N) abits(N)) = return (m n + a)

--- valid for sufficiently wide bit-vectors (N greater than eight) ---bool bit8 (xbits(N)) with N gt 8 = return (xlt8gt)

An L3 type error will arise if ever an application of the operation lsquobit8rsquo violates the bit widthconstraint Note that vector width variables (such as lsquoNnatrsquo above) can be used as if they werea regular variables in the definitional body of an operation

113 ComponentsWhen specifying instruction set architectures the two most significant programmerrsquos modelcomponents are typically the main memory and a collection of general purpose registers In theMIPS architecture for example there are thirty-two general purpose registers which may berepresented using the following map

declare gpr bits(5) -gt bits(64)

The statement

gpr(d) lt- gpr(r)10An compile time error will arise if the type checker is not able to infer all types the final definition must be

free of type variables

11

then expresses moving a value from register lsquorrsquo to register lsquodrsquo However register a memory accessis frequently more complicated than this in particular registers can be banked and memory canbe complex11 As such it is often necessary to specify collections of operations for accessing(reading and writing) these components With the MIPS example register zero is special (it isa constant value) and so one could define the following operations

bits(64) read_gpr (nbits(5)) = if n == 0 then 0 else gpr (n)unit write_gpr (vbits(64) nbits(5)) = when n ltgt 0 do gpr (n) lt- v

Thus the previous register transfers would now be specified as follows

write_gpr (read_gpr (n) d)

This precise style of specification is not entirely satisfying though since it departs in appearancefrom the pseudo code found in MIPS reference manuals The L3 language provides a specialmechanism for specifying a pair of operations that read and write state components With theMIPS example the following declaration can be made

component GPR (nbits(5)) bits(64)

value = if n == 0 then 0 else gpr(n)assign value = when n ltgt 0 do gpr(n) lt- value

One can then write

GPR(d) lt- GPR(r)

which is closer to the syntax used in the MIPS reference manuals The lsquocomponentrsquo constructeffectively provides a controlled form of operator overloading whereby the lsquoassignrsquo operation12

is select when the operator name appears on the left-hand side of an assignment (lsquolt-rsquo) and thelsquovaluersquo operation13 is applied otherwise Semantically these two operations are exactly the sameas the manually defined versions lsquowrite_gprrsquo and lsquoread_gprrsquo The ldquowriterdquo operation will alwayshave a lsquounitrsquo return type Users are free to specify the ldquoreadrdquo and ldquowriterdquo operations in any mannerthat they deem appropriate however the ldquowriterdquo operation cannot be defined recursively norcan the ldquoreadrdquo operation call the ldquowriterdquo operation

114 RecursionThe language permits the definition of recursive operations It is not possible to define mutuallyrecursive operations

The L3 language has been designed to act as an authoring front-end for the HOL4 theoremprover facilitating the task of writing instruction set specifications In order to successfullyimport an L3 specification it is necessary for the HOL4 system to prove that every user defined

11ARM registers are banked according to processor mode Memory can often be accessed with big- and little-endian byte ordering Special treatment may be needed for unaligned memory addresses for example when readinga 16-bit value from an odd address There may also be address translation (virtualisation) and memory hierarchies(caching)

12In this example the ldquowriterdquo operations is internally called lsquowriteGPRrsquo13Internally the ldquoreadrdquo operation is simply called lsquoGPRrsquo

12

operation is total (terminates on all inputs) If an L3 function is non-terminating then it willbe impossible to export that definition to HOL4 If a function is terminating but the standardautomation of HOL4 is unable to construct a termination proof then it may be necessary toprovide the prover with a hint in the form of a measure

Consider the following specification

declare m bits(8) -gt bits(8)

unit load (abits(8) lbits(8) list) =match l

case Nil =gt nothingcase Cons (h t) =gt m(a) lt- h load (a + 1 t)

The lsquoloadrsquo operation recurses over the list lsquolrsquo loading values into the map lsquomrsquo At the time ofwriting this documentation trying to build the exported HOL4 version of this specificationgives rise to the following error message

Initial goal

existRWF R andforallstate a l h t

(l = ht) rArrR ((a + 1wt)state with m = (a =+ h) statem) ((al)state)

Exception raised at TotalDefnDefinebetween beginning of frag 0 and end of frag 0at TotalDefndefnDefine

Unable to prove termination

Try using TotalDefntDefine ltnamegt ltquotationgt lttacgt

This occurs because HOL4 is unable to automatically prove that lsquoloadrsquo always terminates Toget around this problem the original L3 specification can be modified to contain an annotationas follows

unit load (abits(8) lbits(8) list) measure Length(l) =

The metadata lsquomeasure Length(l)rsquo tells HOL4 to examine the length of the list lsquolrsquo since thisvalue will decrease upon each recursive call to lsquoloadrsquo When the length of the list is zero (thelsquoNilrsquo case) there are no recursive calls so termination is guaranteed

The expression occurring after the lsquomeasurersquo keyword must be of type lsquonatrsquo After provid-ing a measure it is still possible that HOL4 will fail to prove termination either because thesupplied measure is incorrect or because the termination proof is non-trivial (requires humanguidance andor custom lemmas) If this occurs then users should either simplifyrewrite theirspecifications or if necessary report the problem

13

115 Instruction Set DefinitionsWhen working with instruction set models it is helpful to construct a datatype that representsthe set of machine (low-level) instructions This datatype constitutes a simple form of abstractsyntax tree (AST) and it can be used to build instruction decoders (identifying machine-codeinstructions and splitting opcodes into sub-fields) instruction encoders (generating opcodes fora given instruction) next-state functions (applying a semantics function for a given instruction)and assembly code parsers

By way of an example consider the MIPS instruction ANDI this instruction has the assemblycode syntax

ANDI rt rs immediate

and the following 32-bit machine-code encoding

31 26 25 21 20 16 15 0

001100 rs rt immediate6 5 5 16

The semantics of this instruction can be expressed with the operation

unit run_ANDI (rsbits(5) rtbits(5) immbits(16)) =GPR(rt) lt- GPR(rs) ampamp ZeroExtend (imm)

One could use this operation to directly specify a next-state function which would be of theform

unit Next =match Fetch -- fetches a 32-bit opcode from memory

middot middot middotcase 001100 rs rt imm =gt run_ANDI (rs rt imm)middot middot middot

This style of specification is direct and concise however it does lack some of the flexibility thatcomes with using an instruction datatype The L3 language provides support for an slightlydifferent style of specification This alternative approach is explained by first examining howone would specify things manually (explicitly) and then showing how L3 can streamline thisprocess

Firstly one could explicitly define an AST datatype for MIPS instructions it would be ofthe form

construct instruction

middot middot middotANDI bits(5) bits(5) bits(16)middot middot middot

14

This datatype provides a suitable constructor for the ANDI instruction It is now possible to definea decoder which maps opcodes onto AST entries for example

instruction Decode (opcbits(32)) =match opc

middot middot middotcase 001100 rs rt imm =gt ANDI (rs rt imm)middot middot middot

This decoder can be used to define our next-state function that is

unit Next = Run (Decode (Fetch))

where lsquoRunrsquo is defined by

unit Run (iinstruction) =match i

middot middot middotcase ANDI (args) =gt run_ANDI (args)middot middot middot

When working with full-scale architecture specifications (where the AST type is large) thereare some clear overheads associated with implementing this approach (in comparison with theAST free version) It becomes challenging to maintain the AST datatype declaration and tokeep it correctly synchronised with the instruction semantics operations (such as lsquorun_ANDIrsquo)and the definition of lsquoRunrsquo Note however that there is great uniformity in the AST datatypedeclaration and also in the definition of lsquoRunrsquo As such L3 is able to automatically define bothof these for the user

To make use of this automation the declaration of lsquorun_ANDIrsquo is simply modified to

define ANDI (rsbits(5) rtbits(5) immbits(16)) =GPR(rt) lt- GPR(rs) ampamp ZeroExtend (imm)

The lsquodefinersquo keyword tells L3 to define a semantics function14 (as before) and to also create anew lsquoinstructionrsquo datatype AST entry furthermore the two will be linked with the automaticconstruction of a lsquoRunrsquo function The lsquoinstructionrsquo type and lsquoRunrsquo function become defined (inscope) following the declaration lsquodefine Runrsquo After this declaration it is no longer possible touse the lsquodefinersquo construct again however it does become possible to define functions such aslsquoDecodersquo and lsquoNextrsquo

Specifications that are based on using lsquodefinersquo gain the benefits of declaring an instructionAST datatype without the downside of laborious coding overheads In the example above theoverhead amounts to one extra line of code this comes from defining a next-state function thatcalls the dedicated decode function followed by a call to lsquoRunrsquo

One of the key advantages of declaring an instruction datatype is that it makes it consider-ably easier to develop tools that work with assembly code syntax (performing parsing encoding

14This function is internally called lsquodfnANDIrsquo instead of lsquorun_ANDIrsquo

15

and pretty-printing) In this case it is relatively easy for example to map between the MIPSinstruction syntax andi $5 $6 1024 and the expression lsquoANDI (5 6 1024)rsquo Defining anencoder in L3 is relatively straightforward for example

bits(32) Encode (iinstruction) =match i

middot middot middotcase ANDI (rs rt imm) =gt 001100 rs rt immmiddot middot middot

Such a function can be used to write a MIPS assembler which would map the assembly codesyntax andi $5 $6 1024 onto the machine-code value 0x30c50400

2 TutorialThis section gives a brief overview of how to install and use L3

Installation The sources for L3 can be downloaded from the following webpage

wwwclcamacuk~acjf3l3

The file l3tarbz2 can be unpacked with the command

$ tar xvjf l3tarbz2

This will create a directory of the form L3-YYYY-MM-DD where the year month and day willcorrespond with the release date The current version of L3 depends upon PolyML 57 whichcan be obtained from the site polymlorg If PolyML is installed then L3 can be built as follows

$ cd L3-YYYY-MM-DD$ make

Once built the following should appear when you start L315

$ l3ltlt L3 gtgtgt

Users should consider running L3 with the command rlwrap l316

15This assumes that the directory L3-YYYY-MM-DDbin has been added to the PATH environment variable16Details on rlwrap utility can be found at the site freecodecomprojectsrlwrap

16

Basic Interaction The command prompt for L3 is essentially the read-eval-print loop (REPL)of PolyML As such users are free to write arbitrary Standard ML code The structure Runtimeenables interaction with L3 The following shows an arithmetic evaluation in Standard ML aswell as in the L3 interpreter (evalQ)

gt 1 + 2val it = 3 intgt RuntimeevalQ `0i1 + 2`val it = `0i3` Termterm

Various error messages can occur when using the interpreter for example

gt RuntimeevalQ `1 + 2`Exception- Fail Could not infer all types raised

gt RuntimeevalQ `0i2 div 0`Exception- Except (Div SOME (div (int [`0i2` `0i0`]))) raised

The first error occurs because unannotated number literals are regarded as bit-vector values andhere the vector width cannot be inferred

L3 declarations can be made using the function loadQ The following sequence shows thedeclaration and manipulation of a global variable

gt RuntimeloadQ `declare n nat`ltVARgt nval it = () unit

gt RuntimeevalQ `n`val it = `UNKNOWNnat` Termterm

gt RuntimeevalQ ` n lt- 3 n `val it = `0n3` Termterm

The global state can be examined using the function show for example

gt Runtimeshow()val it = [(n `0n3`)] Evalterm_stack

The state can be ldquowipedrdquo clean using the function reset and all declarations can be wiped usinglsquoresetAllrsquo for example

gt Runtimereset()val it = () unitgt Runtimeshow()val it = [(n `UNKNOWNnat`)] Evalterm_stack

gt RuntimeresetAll()val it = () unitgt Runtimeshow()val it = [] Evalterm_stack

The function lsquoLoadQrsquo is similar to lsquoloadQrsquo but it performs a lsquoresetAllrsquo before making declarations

17

Constants The structure Consts provides various functions for working with L3 constantsMany of the operation in the Consts structure will be of little interest to end-users however itcan be used to display some helpful information

The function ConstslookupConst can be used to lookup an operation for example

gt ConstslookupConst Log2val it = Primitive [(bits(a) -gt bits(a) -) (nat -gt nat -)] const

Since lsquoLog2rsquo is a primitive operation only the valid types (ordered by overload priority) are showWith user operations the internal representation (definition) of the operation will be shownfor example

gt RuntimeLoadQ `unit demo () = ()`gt ConstslookupConst demoval it = Definition (Abs ([(_ (unit -))] unit -gt unit `()`) NONE 1)

Constsconst

The functions ConstslistDefinitions and ConstslistExceptions provide details of all useroperations and exceptions respectively The function lsquoConstsstatsrsquo gives a summary of all thecurrent declarations

gt Constsstats()Primitives 188Destructors 5Constructors 0Accessors 0Exceptions 0User operations 1Instruction definitions 0

Here the constructors for primitive types (such as lsquoConsrsquo) are counted under ldquoprimitivesrdquo

Types The Types structure can be used to display information relating to L3 types In partic-ular this structure provides the functions TypeslookupConst and TypeslistConsts which aredemonstrated below

gt RuntimeloadQ `construct enum One Two Three`gt TypeslistConsts()val it =

[(enumeq = true ast = false def = Constructors (Enum ltdict(3)gt) num = 0)]

(string typeconst) list

gt TypeslookupConst intval it = SOME eq = true ast = false def = BaseType num = ~1

typeconst option

18

Loading and Exporting Specifications When writing an L3 specification it is expected thatuser declarations will be contained in an L3 source file A sample instruction set specification(tinyspec) can be found in the L3 distribution subdirectory examples This specification isbased on Thackerrsquos pedagogical Tiny 3 architecture it can be loaded as follows

gt RuntimeLoadF tinyspecLoading tinyspecltTYPgt regTltTYPgt wordTmiddot middot middotltFUNgt test_progDone

The string argument to the functions RuntimeloadF and RuntimeLoadF can be in the form ofa comma separated list of files which will be loaded in order That is the call

RuntimeloadF aspec bspec

will load aspec followed by bspecThe function HolExportexport will export the current L3 specification in the form of an

HOL4 script for example

gt HolExportexport tinyraiseexception okfunction okmiddot middot middotmextend skipmunextend skipCreated file tinyScriptsmlCreated file tinyLibsmlCreated file tinyLibsigDone

The function HolExportspec provides a convenient shortcut for performing LoadF and exportusing just a single call for example HolExportspec (tinyspec tiny) will perform theload and export presented above

L3 is capable of exporting two styles of HOL specification an explicitly monadic version(based on state_transformerTheory) and a version that directly manipulates state using let-expressions (which is the default style) For example a monadic version of the Tiny specifi-cation can be exported using the command HolExportspec (tinyspec tiny monadic)Other export options include sigdocs nosigdocs (for setting HOLrsquos TheoryPPinclude_docstrace variable) bigrecords nobigrecords (for controlling HOLrsquos Datatypebig_record_size)and underflowbefore nounderflowbefore (for selecting the required IEEE 754 underflow be-haviour)

Generated HOL4 specifications are not designed to be manually edited (or human readable)To build an L3 specification script the HOL library Import is needed This library is currentlylocated in the directory $HOL_DIRexamplesl3-machine-codecommon and so adding this path tothe INCLUDES variable of a local Holmakefile is recommended The examplesl3-machine-codedirectory contains various examples of using L3 generated specifications

19

Testing Specifications Having written an L3 specification it is fairly easy to write code (inStandard ML) that runs test vectors Code for running the tinyspec example can be found inthe file run-tinyspec In this test harness the Tiny state is initialised and a small test programis loaded simply by evaluating the expression lsquoinitialize (test_prog)rsquo

It is also possible to evaluate (run) models that have been exported to HOL4 The filerun-tinysml shows how this can be accomplished for the Tiny example

20

A Primitive Types and OperationsThe primitive types are as follows

unit bool char nat int bits(middot) rounding

There are two infix type constructors lsquorsquo for pairs and lsquo-gtrsquo for maps There are also postfix typeconstructors lsquosetrsquo lsquooptionrsquo and lsquolistrsquo for example sets of strings are represented by the typelsquostring setrsquo The following sections describe these primitive types together with some detailsof associated operations The following constants and operations are available

nullary () Nil None false roundTiesToEven roundTowardNegativeroundTowardPositive roundTowardZero true

prefix - ~ Abs Cardinality Cons Difference Drop Element FP32_AbsFP32_Add FP32_Equal FP32_IsNan FP32_LessThan FP32_MulFP32_Neg FP32_Sub FP64_Abs FP64_Add FP64_Equal FP64_IsNanFP64_LessThan FP64_Mul FP64_Neg FP64_Sub FromBinStringFromDecString FromHexString Fst Head IndexOf InitMapIntersection IsAlpha IsAlphaNum IsDigit IsHexDigit IsLowerIsMember IsSome IsSubset IsUpper Length Log2 Max Min MsbQuotRem Remove RemoveDuplicates RemoveExcept ReverseSetOfList SignExtend SignedMax SignedMin Size Snd Some TailTake ToLower ToUpper Union Update ValOf ZeroExtend not

infix = ampamp + - lt lt+ lt= lt=+ ltgt == gt gt+ gt= gt=+ ^ || gtgtltlt gtgt+ ltlt gtgt and div in insert mod notin or quot rem

sdivsmodother middot ltmiddotgt middot ltmiddotmiddotgt [middot] fields splitl splitr tokens

Many arithmetic operations are overloaded Unless otherwise stated the order of selection islsquobits(middot)rsquo lsquonatrsquo lsquointrsquo and then lsquobool listrsquo

A1 UnitThe type lsquounitrsquo represents the singleton set containing the value lsquo()rsquo The primary use of thistype is as the return type for procedures

A2 BoolThe type lsquoboolrsquo represents the two element set B = lsquotruersquo lsquofalsersquo The following standardBoolean operations are available

negation not bool rarr boolconjunction and booltimes bool rarr booldisjunction or booltimes bool rarr boolequality == αtimesα rarr boolnon-equality ltgt = αtimesα rarr bool

21

The infix operators lsquoandrsquo and lsquoorrsquo are interpreted with short-circuit evaluation for example in theexpression lsquofalse and f()rsquo the value of lsquof()rsquo is not computed as the overall expression will alwaysevaluate to false This short-circuiting influences the side-effects that occur during expressionevaluation

There are two prefix symbols for logical negation (these are semantically identical) with lsquorsquobinding slightly tighter than lsquonotrsquo This distinction is becomes significant when working withequalities for example lsquonot a == brsquo is taken to be not(a = b) whereas lsquoa == brsquo is (nota) = b

Equality is only defined with respect to equality types represented here by the type variableα An equality type is any type built without the used of the map operator lsquo-gtrsquo

A3 NatThe type lsquonatrsquo represents the natural numbers N = 0 1 2 The following operations areavailable

logarithm (base two) Log2 nat rarr natminimum value Min nattimes nat rarr natmaximium value Max nattimes nat rarr natless than lt nattimes nat rarr boolgreater than gt nattimes nat rarr boolless than or equal to lt= nattimes nat rarr boolgreater than or equal to gt= nattimes nat rarr booladdition + nattimes nat rarr natsubtraction - nattimes nat rarr natmultiplication nattimes nat rarr natexponentiation nattimes nat rarr natdivision div nattimes nat rarr natmodulus mod nattimes nat rarr nat

The lsquodivrsquo and lsquomodrsquo operations satisfy the following property

foralln 0 lt n =rArr forallk k = (k div n) lowast n+ (k mod n) and (k mod n) lt n

The expressions lsquoLog2(0)rsquo lsquox div 0rsquo and lsquox mod 0rsquo are all undefined 17

A4 IntThe type lsquointrsquo represents the integers Z = Ncupminus1minus2minus3 The following operations areavailable

17The interpreter will raise an exception when attempting to evaluate them

22

unary minus - int rarr intabsolute value Abs int rarr intminimum value Min inttimes int rarr intmaximum value Max inttimes int rarr intless than lt inttimes int rarr boolgreater than gt inttimes int rarr boolless than or equal to lt= inttimes int rarr boolgreater than or equal to gt= inttimes int rarr booladdition + inttimes int rarr intsubtraction - inttimes int rarr intmultiplication inttimes int rarr intexponentiation inttimes nat rarr intquotient and remainder QuotRem inttimes int rarr inttimes intquotient quot inttimes int rarr intremainder rem inttimes int rarr intdivision div inttimes int rarr intmodulus mod inttimes int rarr int

The operation lsquoAbsrsquo gives an positive integer value for example lsquoAbs(-2)rsquo = lsquo2rsquo The integeroperations lsquoquotrsquo and lsquodivrsquo are related to natural number division as follows

i quot j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

and

i div j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(minusi) div n(j))minus 1 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i and n(i) mod n(minusj) = 0

minus z(n(i) div n(minusj))minus 1 j lt 0 and 0 le i and n(i) mod n(minusj) = 0

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

where z NrarrZ and n ZrarrN are value preserving maps The lsquoremrsquo and lsquomodrsquo operations satisfythe equations

i rem j =

iminus (i quot j) lowast j j = 0

undefined j = 0i mod j =

iminus (i div j) lowast j j = 0

undefined j = 0

A5 Bit-vectorsThe type lsquobits(n)rsquo represents fixed-width (n-bit) words also known as bit-vectors for examplebits(32) is the type of 32-bit machine words18 The bits type can be viewed as representing

18These are called double-words (dword) in the x86 architecture and simply words in the ARM architecture

23

the set Zn = 0 1 2nminus1 for some 0 lt n At the type system level no distinction is madebetween signed and unsigned words however some operations (such as orderings) have signedand unsigned variants

The following bit-vector operations are available

1rsquos complement ~ bits(n) rarr bits(n)2rsquos complement - bits(n) rarr bits(n)absolute value Abs bits(n) rarr bits(n)logarithm (base two) Log2 bits(n) rarr bits(n)zero-extend ZeroExtend bits(m) rarr bits(n)sign-extend SignExtend bits(m) rarr bits(n)reverse bits Reverse bits(n) rarr bits(n)minimum value (u) Min bits(n)times bits(n) rarr bits(n)maximum value (u) Max bits(n)times bits(n) rarr bits(n)minimum value (s) SignedMin bits(n)times bits(n) rarr bits(n)maximum value (s) SignedMax bits(n)times bits(n) rarr bits(n)widthsize Size bits(n) rarr natmost-significant (sign) bit Msb bits(n) rarr boolbit value middot ltmiddotgt bits(n)times nat rarr boolbit field middot ltmiddotmiddotgt bits(m)times nattimes nat rarr bits(n)concatenation bits(m)times bits(n) rarr bits(p)duplication ^ bits(m)times nat rarr bits(n)less than (s) lt bits(n)times bits(n) rarr boolgreater than (s) gt bits(n)times bits(n) rarr boolless than or equal to (s) lt= bits(n)times bits(n) rarr boolgreater than or equal to (s) gt= bits(n)times bits(n) rarr boolless than (u) lt+ bits(n)times bits(n) rarr boolgreater than (u) gt+ bits(n)times bits(n) rarr boolless than or equal to (u) lt=+ bits(n)times bits(n) rarr boolgreater than or equal to (u) gt=+ bits(n)times bits(n) rarr booladdition + bits(n)times bits(n) rarr bits(n)subtraction - bits(n)times bits(n) rarr bits(n)multiplication bits(n)times bits(n) rarr bits(n)quotient (s) quot bits(n)times bits(n) rarr bits(n)remained (s) rem bits(n)times bits(n) rarr bits(n)division (u) div bits(n)times bits(n) rarr bits(n)modulus (u) mod bits(n)times bits(n) rarr bits(n)division (s) sdiv bits(n)times bits(n) rarr bits(n)modulus (s) smod bits(n)times bits(n) rarr bits(n)bitwise conjunction ampamp bits(n)times bits(n) rarr bits(n)bitwise disjunction || bits(n)times bits(n) rarr bits(n)bitwise exclusive-or bits(n)times bits(n) rarr bits(n)

Unsigned operations are labelled with (u) and signed operations are labelled with (s)The shift operations support shifting by either a bit-vector value or by a natural number value

The overloading is resolved such that the lsquonatrsquo variant is selected over the lsquobits(middot)rsquo version Theshift operations are

24

left-shift ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (u) gtgt+ bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (s) gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate left ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate right gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

A number of operations are undefined depending on the types of their domain and rangeThis is detailed in the following table

Operation Undefined when

ZeroExtend(x`n)`m m lt nSignExtend(x`n)`m m lt n(x`m)ltpgt m le p(x`m)lthlgt`n n = h+ 1minus l or h lt l orm le h((xm) (yn))`p p = m+ n((x`m) ^ n)`p p = m middot n (which covers n = 0)

The type checker will fail when these conditions are obviously violated Alternatively the inter-preter may raise a runtime error when these conditions are not met

As before the expressions lsquoLog2(0)rsquo lsquox quot 0rsquo lsquox rem 0rsquo lsquox div 0rsquo and lsquox mod 0rsquo are allundefined

A6 Bit-stringsVarious bit-string operation are defined over the type lsquobool listrsquo These are listed below

bit value middot ltmiddotgt bool listtimes nat rarr boolbit field middot ltmiddotmiddotgt bool listtimes nattimes nat rarr bool listconcatenation bool listtimes bool list rarr bool listduplication ^ bool listtimes nat rarr bool listaddition + bool listtimes bool list rarr bool listbitwise conjunction ampamp bool listtimes bool list rarr bool listbitwise disjunction || bool listtimes bool list rarr bool listbitwise exclusive-or bool listtimes bool list rarr bool listleft-shift ltlt bool listtimes nat rarr bool listright-shift gtgt+ bool listtimes nat rarr bool listrotate-right gtgt bool listtimes nat rarr bool list

The bit value operation gives the truth value of a bit-string at a given bit position for example

lsquo0s1101lt0gtrsquo = lsquotruersquo lsquo0s1101lt1gtrsquo = lsquofalsersquo lsquo0s1101lt2gtrsquo = lsquotruersquolsquo0s1101lt3gtrsquo = lsquotruersquo lsquo0s1101lt4gtrsquo = lsquofalsersquo lsquo0s1101lt5gtrsquo = lsquofalsersquo

25

The least-significant bit (position zero) occurs to the right of the bit-string The bit value oper-ation gives lsquofalsersquo when the bit position is greater than the size of the bit-string

The bit field operation extracts a range of bits from a bit-string For example

lsquo0s1101lt31gtrsquo = lsquo0s110rsquo and lsquo0s1101lt52gtrsquo = lsquo0s0011rsquo

In the bit-string expression xlthlgt the size of the result is always h + 1 minus l and the result isundefined when h lt l

Bit-string addition does not require the arguments to be of the same size and it gives anon-truncated result For example

lsquo0s101 + 0s1rsquo = lsquo0s110rsquo and lsquo0s101 + 0s11rsquo = lsquo0s1000rsquo

The operation ltlt performs a left-shift for example lsquo0s1101 ltlt 2rsquo = lsquo0s110100rsquo The oper-ation lsquorsquo is bit-string concatenation and lsquo^rsquo is duplication for example

lsquo0s101 0s11rsquo = lsquo0s10111rsquo and lsquo0s101 ^ 3rsquo = lsquo0s101101101rsquo

Regular list operations work as one would expect over bit-strings for example lsquoHead (0s101)rsquois a valid expression with value lsquotruersquo

A7 Characters and StringsThe following built-in functions are available for characters and strings

is alphabetic IsAlpha char rarr boolis alpha-numeric IsAlphaNum char rarr boolis decimal digit IsDigit char rarr boolis hexadecimal digit IsHexDigit char rarr boolis lowercase IsLower char rarr boolis uppercase IsUpper char rarr boolparse binary FromBinString string rarr num optionparse decimal FromDecString string rarr num optionparse hexadecimal FromHexString string rarr num optionconvert to lowercase ToLower string rarr stringconvert to uppercase ToUpper string rarr string

The following string operations are useful for parsing

split from the left splitl (char rarr bool) times string rarr string times stringsplit from the right splitr (char rarr bool) times string rarr string times stringsplit into fields fields (char rarr bool) times string rarr string listsplit into tokens tokens (char rarr bool) times string rarr string list

These are based on the SML functions Substringsplitl Substringsplitr Stringfieldsand Stringtokens Character predicates are declared using special syntax for example theexpression

splitl space or hexdigit and not in set a f ( 12bcab)

gives the result lsquo( 12bc ab)rsquo

26

A8 Floating-pointThe L3 language does not provide specialised types for representing floating-point numbersHowever 32-bit (single precision) and 64-bit (double precision) bit-vector values can be treatedas floating-point numbers the following IEEE compliant encoding formats are assumed

31 30 23 22 0

s e m1 8 23

63 62 52 51 0

s e m1 11 52

Here lsquosrsquo is the sign bit (set to lsquo1rsquo for negative numbers) lsquoersquo is a biased exponent value and lsquomrsquo is thesignificand The following constants and operations are available (where lsquofprsquo stands for bits(32)or bits(64) depending on the name of the operation)

rounding modes roundTiesToEvenroundTowardPositiveroundTowardNegativeroundTowardZero

ieee_rounding

flags (record) DivideByZero InvalidOpOverflow PrecisionUnderflow

ieee_flagsrarrbool

comparison values FP_LT FP_EQ FP_GT FP_UN ieee_compare

convert format FP32_ToFP64 fp32rarrfp64convert format FP64_ToFP32 ieee_roundingtimes fp64rarrfp32convert format FP64_ToFP32_ ieee_roundingtimes fp64rarr

ieee_flagstimes fp32from integer FP32|64_FromInt ieee_roundingtimes intrarrfpto integer FP32|64_ToInt ieee_roundingtimes fprarrint optionfrom string FP32|64 stringrarrfp

negative zero FP32|64_NegZero fppositive zero FP32|64_PosZero fpnegative infinity FP32|64_NegInf fppositive infinity FP32|64_PosInf fpa quiet NaN FP32|64_qNan fpa signalling NaN FP32|64_sNan fp

is integral FP32|64_IsIntegral fprarrboolis finite FP32|64_IsFinite fprarrboolis NaN FP32|64_IsNan fprarrboolis signalling NaN FP32|64_IsSignallingNan fprarrboolis normal FP32|64_IsNormal fprarrboolis sub-normal FP32|64_IsSubnormal fprarrboolis zero FP32|64_IsZero fprarrbool

27

comparison FP32|64_Compare fptimes fprarrieee_compareequality FP32|64_Equal fptimes fprarrboolless than FP32|64_LessThan fptimes fprarrboolless than or equal FP32|64_LessEqual fptimes fprarrboolgreater than FP32|64_GreaterThan fptimes fprarrboolgreater than or equal FP32|64_GreaterEqual fptimes fprarrbool

absolute FP32|64_Abs fprarrfpnegation FP32|64_Neg fprarrfpsquare root FP32|64_Sqrt ieee_roundingtimes fprarrfp(with flags) FP32|64_Sqrt_ ieee_roundingtimes fprarrieee_flagstimes fpaddition FP32|64_Add ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Add_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpsubtraction FP32|64_Sub ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Sub_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpmultiplication FP32|64_Mul ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Mul_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpfused multiply-add FP32|64_MulAdd ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulAdd_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpfused multiply-sub FP32|64_MulSub ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulSub_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpdivision FP32|64_Div ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Div_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fp

The L3 interpreter supports evaluation for 32-bit and 64-bit floating-point expressions but onlywhen running on an x86 machine that supports SSE2 extensions (Pentium 4 and later) Thefused multiply-addsub operations can only be interpreted on machines supporting the FMAextension which came in with the 4th generation (Haswell) Intel processors These restrictionsalso apply to any Standard ML code that is generated by L3

The IEEE 754 standard permits a number of different ways to flag underflow L3 predomi-nantly supports the x86 interpretation which detects underflow after rounding However whenexporting to HOL4 it is possible to choose detection before rounding which for example issuited to ARM instruction set models

A9 Miscellaneous operationsThe following operations are available

pair constructor αtimes β rarr αtimes βfirst of pair Fst αtimes β rarr αsecond of pair Snd αtimes β rarr β

casting [middot] α rarr βinitialise a map InitMap α rarr (βrarrα)

28

option constructor Some αrarrα optionoption projection ValOf α option rarr αoption test IsSome α option rarr bool

set membership in αtimesα set rarr boolset non-membership notin αtimesα set rarr boolset insertion insert αtimesα set rarrα setset union Union α settimesα set rarrα setset intersection Intersect α settimesα set rarrα setset difference Difference α settimesα set rarrα setset subset test IsSubset α settimesα set rarr boolset cardinality Cardinality α setrarr natset from a list SetOfList α list rarrα set

empty list Nil α listlist constructor Cons αtimesα list rarr α listlist head Head α list rarr αlist tail Tail α list rarr α listlist length Length α list rarr natlist concatenation α listtimesα list rarr α listlist flatten Concat α list list rarr α listlist element Element nattimesα list rarr αlist prefix Take nattimesα list rarr α listlist drop prefix Drop nattimesα list rarr α listlist pad left PadLeft αtimes nattimesα list rarr α listlist pad right PadRight αtimes nattimesα list rarr α listlist update Update αtimes nattimesα list rarr α listlist difference Remove α listtimesα list rarr α listlist intersection RemoveExcept α listtimesα list rarr α listlist without duplicates RemoveDuplicates α listrarr α listlist membership IsMember αtimesα list rarr boollist member position IndexOf αtimesα list rarr nat option

Sets are only defined over equality types see Appendix A2 The casting map is defined overcast-able types (as represented by the polymorphic type variables α and β) these are the primitivetypes (with the exception of lsquounitrsquo) and user defined enumerated types Assume lsquoEnumrsquo and lsquoEnum2rsquoare declared with

construct Enum One Two Three construct Enum2 Four Five Six Seven

The cast operations are described in Tables 1 to 7

29

Table 1 Cast to lsquoboolrsquo

From Operation Examples

bool identity lsquo[true]boolrsquo = lsquotruersquostring parse bool lsquo[true]boolrsquo = lsquotruersquo

lsquo[false]boolrsquo = lsquofalsersquootherwise undefined

nat is not zero lsquo[0n3]boolrsquo = lsquotruersquolsquo[0n0]boolrsquo = lsquofalsersquo

int is not zero lsquo[-0i1]boolrsquo = lsquotruersquolsquo[0i0]boolrsquo = lsquofalsersquo

bool list is not zero lsquo[0s11]boolrsquo = lsquotruersquolsquo[0s0]boolrsquo = lsquofalsersquo

bits(middot) is not zero lsquo[3`3]boolrsquo = lsquotruersquolsquo[0`3]boolrsquo = lsquofalsersquo

Enum is not the first element lsquo[One]boolrsquo = lsquofalsersquolsquo[Two]boolrsquo = lsquotruersquo

Table 2 Cast to lsquostringrsquo

From Operation Examples

bool name lsquo[true]stringrsquo = lsquotruersquostring identity lsquo[hello]stringrsquo = lsquohellorsquonat decimal lsquo[0n3]stringrsquo = lsquo3rsquoint signed decimal lsquo[-0i1]stringrsquo = lsquo~1rsquobool list binary lsquo[0s11]stringrsquo = lsquo11rsquobits(middot) unsigned hexadecimal lsquo[139`8]stringrsquo = lsquo8BrsquoEnum name lsquo[One]stringrsquo = lsquoOnersquo

30

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

middot middot middotASSERT error -- raise an exceptionproc (1 true) -- the L3 interpreter will never reach this code

In the above the exception is unconditionally raised so the remaining code should be regardedas unreachable (redundant)

1116 Local VariablesThe L3 language supports two varieties of variables mutable and immutable All global vari-ables are mutable The keyword lsquovarrsquo is used to declare new mutable variables with local scopeLocal variables can be introduced anywhere within a statement block and these variables canbe assigned to using the lsquolt-rsquo operator Immutable variables are introduced within a block usingthe syntax lsquox = expr rsquo and this is treated as a let-statement An immutable value cannot beupdated however it can fall out of scope by declaring a new immutable variable with the samename The operators lsquolt-rsquo and lsquo=rsquo are not permitted in expressions

The specification below uses two mutable variables lsquoxrsquo and lsquoyrsquo

var y = zvar x = yif p then xlt30gt lt- 1111 y lt- x + 1

else xlt74gt lt- 1111 y lt- 0 return (x + y)

This could be respecified using immutable variables for example

y = zx = yx y = if p then (x || 00001111 x || 00001111 + 1)

else (x || 11110000 0)return (x + y)

It is not always easy to eliminate mutable variables In this case the second specification ismore cumbersome because the bit-field update has been replace by an explicit mask (bitwise-or)operation This operations has been repeated in specify the value of lsquoyrsquo because assignments arenot permitted in expressions

Mutable variables can be declared without an initial assignment for example lsquovar xrsquo isequivalent to lsquovar x = UNKNOWNrsquo

1117 PatternMatchingThe language supports match statements and expressions Pattern matching is supported withrespect to literals (see Section 13) constructors9 (immutable) variables wildcards (anonymousvariables) and bit-patterns

9This includes matching on tuples as well as lsquoNonersquo lsquoSomersquo lsquoConsrsquo and lsquoNilrsquo Matching on finite sets and recordfields is not possible

9

Given the type declarations

construct enum One Two Three construct data

NoDataData1 string bits(8)Data2 enum bits(16)

the following illustrates a match expression

match y

case -1 NoData or -2 NoData =gt 0`4 -- note use of orcase _ Data1 (hello 11 x 11) =gt x + 1 -- use of bit-patterncase i Data2 (Three 1111 y) =gt [i] + ylt30gtcase 1 Data2 (_ 8) =gt 4case _ =gt 8

The body (right-hand side of lsquo=gtrsquo) of the first case line with a matching pattern is selected Thesymbol lsquo_rsquo is a wildcard and will match any value The lsquoorrsquo construct provides a shorthand forwriting blocks of clauses with differing patterns but the same body

The terms lsquo11 x 11rsquo and lsquo1111 yrsquo are called bit-patterns and they will match against a setof bit-vector values From the type declaration of lsquodatarsquo it is known that the variable lsquoxrsquo mustrepresent a 4-bit value because it occurs in the middle of an 8-bit word (the match requires bitslsquo11rsquo as a prefix and as a suffix) Likewise lsquoyrsquo must be a 12-bit value Multiple variables can occurin a bit-patterns for example lsquo1 x 1 y 0rsquo is a valid bit-pattern The type checker will oftenbe able to infer the type of pattern variables and if this fails type annotations can be added

The lsquopatternrsquo construct can help avoid situations where explicit annotations are repeatedlyrequired (causing clutter in patterns) If for example the variable lsquoimm5rsquo is frequently used tomatch a 5-bit value then the following declaration can be made

pattern imm5 bits(5)

In subsequent code the default type for pattern variable lsquoimm5rsquo will be lsquobits(5)rsquo The lsquopatternrsquoconstruct only influences type checking If a particular type hint is no longer appropriate thenit can be dropped for example one can insert the declaration lsquoclear pattern imm5rsquo

112 Defining Constants and OperationsUsers can construct operational semantics style formal specifications in L3 by defining their ownconstants and operations There is no module system or facility for local definitions all userdefinitions are made at the top-level with global scope User constants and operations cannot beoverloaded or redefined

A pure constant is a nullary (zero argument) operation that is state independent for examplethe following code declares a new constant

bits(32) UINT_MAX = 0xFFFFFFFF

10

The following code declares operations that are nullary but state dependent

declare number Natnat numberPlus1 = return (number + 1)unit incNumber = number lt- numberPlus1

Users can also declare new unary operations which may or may not be state dependent forexample

nat numberMinusN (nnat) = return (number + n) -- state dependentunit decNumber () = number lt- numberMinusN (1)nat mla (mnatnnatanat) = return (m n + a) -- pure

The operation lsquomlarsquo is unary because it takes a single triple as an argument To enhance clarityand avoid misunderstandards users may elect to specify nullary state dependent operations usinga single lsquounitrsquo argument Given the declarations above the expression lsquodecNumber()rsquo gives theclear impression that a call is being made (with possible side-effects) wheres the expressionlsquoincNumberrsquo does not

At the point of declaration operation arguments must be fully type annotated and onlymonomorphic types are allowed10 It is nevertheless possible to declare bit-vector operationsthat are valid with respect to some given set of bit widths for example the following are validdeclarations

--- valid for any bit-vector width N ---bits(N) bv_mla (mbits(N) nbits(N) abits(N)) = return (m n + a)

--- valid for sufficiently wide bit-vectors (N greater than eight) ---bool bit8 (xbits(N)) with N gt 8 = return (xlt8gt)

An L3 type error will arise if ever an application of the operation lsquobit8rsquo violates the bit widthconstraint Note that vector width variables (such as lsquoNnatrsquo above) can be used as if they werea regular variables in the definitional body of an operation

113 ComponentsWhen specifying instruction set architectures the two most significant programmerrsquos modelcomponents are typically the main memory and a collection of general purpose registers In theMIPS architecture for example there are thirty-two general purpose registers which may berepresented using the following map

declare gpr bits(5) -gt bits(64)

The statement

gpr(d) lt- gpr(r)10An compile time error will arise if the type checker is not able to infer all types the final definition must be

free of type variables

11

then expresses moving a value from register lsquorrsquo to register lsquodrsquo However register a memory accessis frequently more complicated than this in particular registers can be banked and memory canbe complex11 As such it is often necessary to specify collections of operations for accessing(reading and writing) these components With the MIPS example register zero is special (it isa constant value) and so one could define the following operations

bits(64) read_gpr (nbits(5)) = if n == 0 then 0 else gpr (n)unit write_gpr (vbits(64) nbits(5)) = when n ltgt 0 do gpr (n) lt- v

Thus the previous register transfers would now be specified as follows

write_gpr (read_gpr (n) d)

This precise style of specification is not entirely satisfying though since it departs in appearancefrom the pseudo code found in MIPS reference manuals The L3 language provides a specialmechanism for specifying a pair of operations that read and write state components With theMIPS example the following declaration can be made

component GPR (nbits(5)) bits(64)

value = if n == 0 then 0 else gpr(n)assign value = when n ltgt 0 do gpr(n) lt- value

One can then write

GPR(d) lt- GPR(r)

which is closer to the syntax used in the MIPS reference manuals The lsquocomponentrsquo constructeffectively provides a controlled form of operator overloading whereby the lsquoassignrsquo operation12

is select when the operator name appears on the left-hand side of an assignment (lsquolt-rsquo) and thelsquovaluersquo operation13 is applied otherwise Semantically these two operations are exactly the sameas the manually defined versions lsquowrite_gprrsquo and lsquoread_gprrsquo The ldquowriterdquo operation will alwayshave a lsquounitrsquo return type Users are free to specify the ldquoreadrdquo and ldquowriterdquo operations in any mannerthat they deem appropriate however the ldquowriterdquo operation cannot be defined recursively norcan the ldquoreadrdquo operation call the ldquowriterdquo operation

114 RecursionThe language permits the definition of recursive operations It is not possible to define mutuallyrecursive operations

The L3 language has been designed to act as an authoring front-end for the HOL4 theoremprover facilitating the task of writing instruction set specifications In order to successfullyimport an L3 specification it is necessary for the HOL4 system to prove that every user defined

11ARM registers are banked according to processor mode Memory can often be accessed with big- and little-endian byte ordering Special treatment may be needed for unaligned memory addresses for example when readinga 16-bit value from an odd address There may also be address translation (virtualisation) and memory hierarchies(caching)

12In this example the ldquowriterdquo operations is internally called lsquowriteGPRrsquo13Internally the ldquoreadrdquo operation is simply called lsquoGPRrsquo

12

operation is total (terminates on all inputs) If an L3 function is non-terminating then it willbe impossible to export that definition to HOL4 If a function is terminating but the standardautomation of HOL4 is unable to construct a termination proof then it may be necessary toprovide the prover with a hint in the form of a measure

Consider the following specification

declare m bits(8) -gt bits(8)

unit load (abits(8) lbits(8) list) =match l

case Nil =gt nothingcase Cons (h t) =gt m(a) lt- h load (a + 1 t)

The lsquoloadrsquo operation recurses over the list lsquolrsquo loading values into the map lsquomrsquo At the time ofwriting this documentation trying to build the exported HOL4 version of this specificationgives rise to the following error message

Initial goal

existRWF R andforallstate a l h t

(l = ht) rArrR ((a + 1wt)state with m = (a =+ h) statem) ((al)state)

Exception raised at TotalDefnDefinebetween beginning of frag 0 and end of frag 0at TotalDefndefnDefine

Unable to prove termination

Try using TotalDefntDefine ltnamegt ltquotationgt lttacgt

This occurs because HOL4 is unable to automatically prove that lsquoloadrsquo always terminates Toget around this problem the original L3 specification can be modified to contain an annotationas follows

unit load (abits(8) lbits(8) list) measure Length(l) =

The metadata lsquomeasure Length(l)rsquo tells HOL4 to examine the length of the list lsquolrsquo since thisvalue will decrease upon each recursive call to lsquoloadrsquo When the length of the list is zero (thelsquoNilrsquo case) there are no recursive calls so termination is guaranteed

The expression occurring after the lsquomeasurersquo keyword must be of type lsquonatrsquo After provid-ing a measure it is still possible that HOL4 will fail to prove termination either because thesupplied measure is incorrect or because the termination proof is non-trivial (requires humanguidance andor custom lemmas) If this occurs then users should either simplifyrewrite theirspecifications or if necessary report the problem

13

115 Instruction Set DefinitionsWhen working with instruction set models it is helpful to construct a datatype that representsthe set of machine (low-level) instructions This datatype constitutes a simple form of abstractsyntax tree (AST) and it can be used to build instruction decoders (identifying machine-codeinstructions and splitting opcodes into sub-fields) instruction encoders (generating opcodes fora given instruction) next-state functions (applying a semantics function for a given instruction)and assembly code parsers

By way of an example consider the MIPS instruction ANDI this instruction has the assemblycode syntax

ANDI rt rs immediate

and the following 32-bit machine-code encoding

31 26 25 21 20 16 15 0

001100 rs rt immediate6 5 5 16

The semantics of this instruction can be expressed with the operation

unit run_ANDI (rsbits(5) rtbits(5) immbits(16)) =GPR(rt) lt- GPR(rs) ampamp ZeroExtend (imm)

One could use this operation to directly specify a next-state function which would be of theform

unit Next =match Fetch -- fetches a 32-bit opcode from memory

middot middot middotcase 001100 rs rt imm =gt run_ANDI (rs rt imm)middot middot middot

This style of specification is direct and concise however it does lack some of the flexibility thatcomes with using an instruction datatype The L3 language provides support for an slightlydifferent style of specification This alternative approach is explained by first examining howone would specify things manually (explicitly) and then showing how L3 can streamline thisprocess

Firstly one could explicitly define an AST datatype for MIPS instructions it would be ofthe form

construct instruction

middot middot middotANDI bits(5) bits(5) bits(16)middot middot middot

14

This datatype provides a suitable constructor for the ANDI instruction It is now possible to definea decoder which maps opcodes onto AST entries for example

instruction Decode (opcbits(32)) =match opc

middot middot middotcase 001100 rs rt imm =gt ANDI (rs rt imm)middot middot middot

This decoder can be used to define our next-state function that is

unit Next = Run (Decode (Fetch))

where lsquoRunrsquo is defined by

unit Run (iinstruction) =match i

middot middot middotcase ANDI (args) =gt run_ANDI (args)middot middot middot

When working with full-scale architecture specifications (where the AST type is large) thereare some clear overheads associated with implementing this approach (in comparison with theAST free version) It becomes challenging to maintain the AST datatype declaration and tokeep it correctly synchronised with the instruction semantics operations (such as lsquorun_ANDIrsquo)and the definition of lsquoRunrsquo Note however that there is great uniformity in the AST datatypedeclaration and also in the definition of lsquoRunrsquo As such L3 is able to automatically define bothof these for the user

To make use of this automation the declaration of lsquorun_ANDIrsquo is simply modified to

define ANDI (rsbits(5) rtbits(5) immbits(16)) =GPR(rt) lt- GPR(rs) ampamp ZeroExtend (imm)

The lsquodefinersquo keyword tells L3 to define a semantics function14 (as before) and to also create anew lsquoinstructionrsquo datatype AST entry furthermore the two will be linked with the automaticconstruction of a lsquoRunrsquo function The lsquoinstructionrsquo type and lsquoRunrsquo function become defined (inscope) following the declaration lsquodefine Runrsquo After this declaration it is no longer possible touse the lsquodefinersquo construct again however it does become possible to define functions such aslsquoDecodersquo and lsquoNextrsquo

Specifications that are based on using lsquodefinersquo gain the benefits of declaring an instructionAST datatype without the downside of laborious coding overheads In the example above theoverhead amounts to one extra line of code this comes from defining a next-state function thatcalls the dedicated decode function followed by a call to lsquoRunrsquo

One of the key advantages of declaring an instruction datatype is that it makes it consider-ably easier to develop tools that work with assembly code syntax (performing parsing encoding

14This function is internally called lsquodfnANDIrsquo instead of lsquorun_ANDIrsquo

15

and pretty-printing) In this case it is relatively easy for example to map between the MIPSinstruction syntax andi $5 $6 1024 and the expression lsquoANDI (5 6 1024)rsquo Defining anencoder in L3 is relatively straightforward for example

bits(32) Encode (iinstruction) =match i

middot middot middotcase ANDI (rs rt imm) =gt 001100 rs rt immmiddot middot middot

Such a function can be used to write a MIPS assembler which would map the assembly codesyntax andi $5 $6 1024 onto the machine-code value 0x30c50400

2 TutorialThis section gives a brief overview of how to install and use L3

Installation The sources for L3 can be downloaded from the following webpage

wwwclcamacuk~acjf3l3

The file l3tarbz2 can be unpacked with the command

$ tar xvjf l3tarbz2

This will create a directory of the form L3-YYYY-MM-DD where the year month and day willcorrespond with the release date The current version of L3 depends upon PolyML 57 whichcan be obtained from the site polymlorg If PolyML is installed then L3 can be built as follows

$ cd L3-YYYY-MM-DD$ make

Once built the following should appear when you start L315

$ l3ltlt L3 gtgtgt

Users should consider running L3 with the command rlwrap l316

15This assumes that the directory L3-YYYY-MM-DDbin has been added to the PATH environment variable16Details on rlwrap utility can be found at the site freecodecomprojectsrlwrap

16

Basic Interaction The command prompt for L3 is essentially the read-eval-print loop (REPL)of PolyML As such users are free to write arbitrary Standard ML code The structure Runtimeenables interaction with L3 The following shows an arithmetic evaluation in Standard ML aswell as in the L3 interpreter (evalQ)

gt 1 + 2val it = 3 intgt RuntimeevalQ `0i1 + 2`val it = `0i3` Termterm

Various error messages can occur when using the interpreter for example

gt RuntimeevalQ `1 + 2`Exception- Fail Could not infer all types raised

gt RuntimeevalQ `0i2 div 0`Exception- Except (Div SOME (div (int [`0i2` `0i0`]))) raised

The first error occurs because unannotated number literals are regarded as bit-vector values andhere the vector width cannot be inferred

L3 declarations can be made using the function loadQ The following sequence shows thedeclaration and manipulation of a global variable

gt RuntimeloadQ `declare n nat`ltVARgt nval it = () unit

gt RuntimeevalQ `n`val it = `UNKNOWNnat` Termterm

gt RuntimeevalQ ` n lt- 3 n `val it = `0n3` Termterm

The global state can be examined using the function show for example

gt Runtimeshow()val it = [(n `0n3`)] Evalterm_stack

The state can be ldquowipedrdquo clean using the function reset and all declarations can be wiped usinglsquoresetAllrsquo for example

gt Runtimereset()val it = () unitgt Runtimeshow()val it = [(n `UNKNOWNnat`)] Evalterm_stack

gt RuntimeresetAll()val it = () unitgt Runtimeshow()val it = [] Evalterm_stack

The function lsquoLoadQrsquo is similar to lsquoloadQrsquo but it performs a lsquoresetAllrsquo before making declarations

17

Constants The structure Consts provides various functions for working with L3 constantsMany of the operation in the Consts structure will be of little interest to end-users however itcan be used to display some helpful information

The function ConstslookupConst can be used to lookup an operation for example

gt ConstslookupConst Log2val it = Primitive [(bits(a) -gt bits(a) -) (nat -gt nat -)] const

Since lsquoLog2rsquo is a primitive operation only the valid types (ordered by overload priority) are showWith user operations the internal representation (definition) of the operation will be shownfor example

gt RuntimeLoadQ `unit demo () = ()`gt ConstslookupConst demoval it = Definition (Abs ([(_ (unit -))] unit -gt unit `()`) NONE 1)

Constsconst

The functions ConstslistDefinitions and ConstslistExceptions provide details of all useroperations and exceptions respectively The function lsquoConstsstatsrsquo gives a summary of all thecurrent declarations

gt Constsstats()Primitives 188Destructors 5Constructors 0Accessors 0Exceptions 0User operations 1Instruction definitions 0

Here the constructors for primitive types (such as lsquoConsrsquo) are counted under ldquoprimitivesrdquo

Types The Types structure can be used to display information relating to L3 types In partic-ular this structure provides the functions TypeslookupConst and TypeslistConsts which aredemonstrated below

gt RuntimeloadQ `construct enum One Two Three`gt TypeslistConsts()val it =

[(enumeq = true ast = false def = Constructors (Enum ltdict(3)gt) num = 0)]

(string typeconst) list

gt TypeslookupConst intval it = SOME eq = true ast = false def = BaseType num = ~1

typeconst option

18

Loading and Exporting Specifications When writing an L3 specification it is expected thatuser declarations will be contained in an L3 source file A sample instruction set specification(tinyspec) can be found in the L3 distribution subdirectory examples This specification isbased on Thackerrsquos pedagogical Tiny 3 architecture it can be loaded as follows

gt RuntimeLoadF tinyspecLoading tinyspecltTYPgt regTltTYPgt wordTmiddot middot middotltFUNgt test_progDone

The string argument to the functions RuntimeloadF and RuntimeLoadF can be in the form ofa comma separated list of files which will be loaded in order That is the call

RuntimeloadF aspec bspec

will load aspec followed by bspecThe function HolExportexport will export the current L3 specification in the form of an

HOL4 script for example

gt HolExportexport tinyraiseexception okfunction okmiddot middot middotmextend skipmunextend skipCreated file tinyScriptsmlCreated file tinyLibsmlCreated file tinyLibsigDone

The function HolExportspec provides a convenient shortcut for performing LoadF and exportusing just a single call for example HolExportspec (tinyspec tiny) will perform theload and export presented above

L3 is capable of exporting two styles of HOL specification an explicitly monadic version(based on state_transformerTheory) and a version that directly manipulates state using let-expressions (which is the default style) For example a monadic version of the Tiny specifi-cation can be exported using the command HolExportspec (tinyspec tiny monadic)Other export options include sigdocs nosigdocs (for setting HOLrsquos TheoryPPinclude_docstrace variable) bigrecords nobigrecords (for controlling HOLrsquos Datatypebig_record_size)and underflowbefore nounderflowbefore (for selecting the required IEEE 754 underflow be-haviour)

Generated HOL4 specifications are not designed to be manually edited (or human readable)To build an L3 specification script the HOL library Import is needed This library is currentlylocated in the directory $HOL_DIRexamplesl3-machine-codecommon and so adding this path tothe INCLUDES variable of a local Holmakefile is recommended The examplesl3-machine-codedirectory contains various examples of using L3 generated specifications

19

Testing Specifications Having written an L3 specification it is fairly easy to write code (inStandard ML) that runs test vectors Code for running the tinyspec example can be found inthe file run-tinyspec In this test harness the Tiny state is initialised and a small test programis loaded simply by evaluating the expression lsquoinitialize (test_prog)rsquo

It is also possible to evaluate (run) models that have been exported to HOL4 The filerun-tinysml shows how this can be accomplished for the Tiny example

20

A Primitive Types and OperationsThe primitive types are as follows

unit bool char nat int bits(middot) rounding

There are two infix type constructors lsquorsquo for pairs and lsquo-gtrsquo for maps There are also postfix typeconstructors lsquosetrsquo lsquooptionrsquo and lsquolistrsquo for example sets of strings are represented by the typelsquostring setrsquo The following sections describe these primitive types together with some detailsof associated operations The following constants and operations are available

nullary () Nil None false roundTiesToEven roundTowardNegativeroundTowardPositive roundTowardZero true

prefix - ~ Abs Cardinality Cons Difference Drop Element FP32_AbsFP32_Add FP32_Equal FP32_IsNan FP32_LessThan FP32_MulFP32_Neg FP32_Sub FP64_Abs FP64_Add FP64_Equal FP64_IsNanFP64_LessThan FP64_Mul FP64_Neg FP64_Sub FromBinStringFromDecString FromHexString Fst Head IndexOf InitMapIntersection IsAlpha IsAlphaNum IsDigit IsHexDigit IsLowerIsMember IsSome IsSubset IsUpper Length Log2 Max Min MsbQuotRem Remove RemoveDuplicates RemoveExcept ReverseSetOfList SignExtend SignedMax SignedMin Size Snd Some TailTake ToLower ToUpper Union Update ValOf ZeroExtend not

infix = ampamp + - lt lt+ lt= lt=+ ltgt == gt gt+ gt= gt=+ ^ || gtgtltlt gtgt+ ltlt gtgt and div in insert mod notin or quot rem

sdivsmodother middot ltmiddotgt middot ltmiddotmiddotgt [middot] fields splitl splitr tokens

Many arithmetic operations are overloaded Unless otherwise stated the order of selection islsquobits(middot)rsquo lsquonatrsquo lsquointrsquo and then lsquobool listrsquo

A1 UnitThe type lsquounitrsquo represents the singleton set containing the value lsquo()rsquo The primary use of thistype is as the return type for procedures

A2 BoolThe type lsquoboolrsquo represents the two element set B = lsquotruersquo lsquofalsersquo The following standardBoolean operations are available

negation not bool rarr boolconjunction and booltimes bool rarr booldisjunction or booltimes bool rarr boolequality == αtimesα rarr boolnon-equality ltgt = αtimesα rarr bool

21

The infix operators lsquoandrsquo and lsquoorrsquo are interpreted with short-circuit evaluation for example in theexpression lsquofalse and f()rsquo the value of lsquof()rsquo is not computed as the overall expression will alwaysevaluate to false This short-circuiting influences the side-effects that occur during expressionevaluation

There are two prefix symbols for logical negation (these are semantically identical) with lsquorsquobinding slightly tighter than lsquonotrsquo This distinction is becomes significant when working withequalities for example lsquonot a == brsquo is taken to be not(a = b) whereas lsquoa == brsquo is (nota) = b

Equality is only defined with respect to equality types represented here by the type variableα An equality type is any type built without the used of the map operator lsquo-gtrsquo

A3 NatThe type lsquonatrsquo represents the natural numbers N = 0 1 2 The following operations areavailable

logarithm (base two) Log2 nat rarr natminimum value Min nattimes nat rarr natmaximium value Max nattimes nat rarr natless than lt nattimes nat rarr boolgreater than gt nattimes nat rarr boolless than or equal to lt= nattimes nat rarr boolgreater than or equal to gt= nattimes nat rarr booladdition + nattimes nat rarr natsubtraction - nattimes nat rarr natmultiplication nattimes nat rarr natexponentiation nattimes nat rarr natdivision div nattimes nat rarr natmodulus mod nattimes nat rarr nat

The lsquodivrsquo and lsquomodrsquo operations satisfy the following property

foralln 0 lt n =rArr forallk k = (k div n) lowast n+ (k mod n) and (k mod n) lt n

The expressions lsquoLog2(0)rsquo lsquox div 0rsquo and lsquox mod 0rsquo are all undefined 17

A4 IntThe type lsquointrsquo represents the integers Z = Ncupminus1minus2minus3 The following operations areavailable

17The interpreter will raise an exception when attempting to evaluate them

22

unary minus - int rarr intabsolute value Abs int rarr intminimum value Min inttimes int rarr intmaximum value Max inttimes int rarr intless than lt inttimes int rarr boolgreater than gt inttimes int rarr boolless than or equal to lt= inttimes int rarr boolgreater than or equal to gt= inttimes int rarr booladdition + inttimes int rarr intsubtraction - inttimes int rarr intmultiplication inttimes int rarr intexponentiation inttimes nat rarr intquotient and remainder QuotRem inttimes int rarr inttimes intquotient quot inttimes int rarr intremainder rem inttimes int rarr intdivision div inttimes int rarr intmodulus mod inttimes int rarr int

The operation lsquoAbsrsquo gives an positive integer value for example lsquoAbs(-2)rsquo = lsquo2rsquo The integeroperations lsquoquotrsquo and lsquodivrsquo are related to natural number division as follows

i quot j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

and

i div j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(minusi) div n(j))minus 1 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i and n(i) mod n(minusj) = 0

minus z(n(i) div n(minusj))minus 1 j lt 0 and 0 le i and n(i) mod n(minusj) = 0

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

where z NrarrZ and n ZrarrN are value preserving maps The lsquoremrsquo and lsquomodrsquo operations satisfythe equations

i rem j =

iminus (i quot j) lowast j j = 0

undefined j = 0i mod j =

iminus (i div j) lowast j j = 0

undefined j = 0

A5 Bit-vectorsThe type lsquobits(n)rsquo represents fixed-width (n-bit) words also known as bit-vectors for examplebits(32) is the type of 32-bit machine words18 The bits type can be viewed as representing

18These are called double-words (dword) in the x86 architecture and simply words in the ARM architecture

23

the set Zn = 0 1 2nminus1 for some 0 lt n At the type system level no distinction is madebetween signed and unsigned words however some operations (such as orderings) have signedand unsigned variants

The following bit-vector operations are available

1rsquos complement ~ bits(n) rarr bits(n)2rsquos complement - bits(n) rarr bits(n)absolute value Abs bits(n) rarr bits(n)logarithm (base two) Log2 bits(n) rarr bits(n)zero-extend ZeroExtend bits(m) rarr bits(n)sign-extend SignExtend bits(m) rarr bits(n)reverse bits Reverse bits(n) rarr bits(n)minimum value (u) Min bits(n)times bits(n) rarr bits(n)maximum value (u) Max bits(n)times bits(n) rarr bits(n)minimum value (s) SignedMin bits(n)times bits(n) rarr bits(n)maximum value (s) SignedMax bits(n)times bits(n) rarr bits(n)widthsize Size bits(n) rarr natmost-significant (sign) bit Msb bits(n) rarr boolbit value middot ltmiddotgt bits(n)times nat rarr boolbit field middot ltmiddotmiddotgt bits(m)times nattimes nat rarr bits(n)concatenation bits(m)times bits(n) rarr bits(p)duplication ^ bits(m)times nat rarr bits(n)less than (s) lt bits(n)times bits(n) rarr boolgreater than (s) gt bits(n)times bits(n) rarr boolless than or equal to (s) lt= bits(n)times bits(n) rarr boolgreater than or equal to (s) gt= bits(n)times bits(n) rarr boolless than (u) lt+ bits(n)times bits(n) rarr boolgreater than (u) gt+ bits(n)times bits(n) rarr boolless than or equal to (u) lt=+ bits(n)times bits(n) rarr boolgreater than or equal to (u) gt=+ bits(n)times bits(n) rarr booladdition + bits(n)times bits(n) rarr bits(n)subtraction - bits(n)times bits(n) rarr bits(n)multiplication bits(n)times bits(n) rarr bits(n)quotient (s) quot bits(n)times bits(n) rarr bits(n)remained (s) rem bits(n)times bits(n) rarr bits(n)division (u) div bits(n)times bits(n) rarr bits(n)modulus (u) mod bits(n)times bits(n) rarr bits(n)division (s) sdiv bits(n)times bits(n) rarr bits(n)modulus (s) smod bits(n)times bits(n) rarr bits(n)bitwise conjunction ampamp bits(n)times bits(n) rarr bits(n)bitwise disjunction || bits(n)times bits(n) rarr bits(n)bitwise exclusive-or bits(n)times bits(n) rarr bits(n)

Unsigned operations are labelled with (u) and signed operations are labelled with (s)The shift operations support shifting by either a bit-vector value or by a natural number value

The overloading is resolved such that the lsquonatrsquo variant is selected over the lsquobits(middot)rsquo version Theshift operations are

24

left-shift ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (u) gtgt+ bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (s) gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate left ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate right gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

A number of operations are undefined depending on the types of their domain and rangeThis is detailed in the following table

Operation Undefined when

ZeroExtend(x`n)`m m lt nSignExtend(x`n)`m m lt n(x`m)ltpgt m le p(x`m)lthlgt`n n = h+ 1minus l or h lt l orm le h((xm) (yn))`p p = m+ n((x`m) ^ n)`p p = m middot n (which covers n = 0)

The type checker will fail when these conditions are obviously violated Alternatively the inter-preter may raise a runtime error when these conditions are not met

As before the expressions lsquoLog2(0)rsquo lsquox quot 0rsquo lsquox rem 0rsquo lsquox div 0rsquo and lsquox mod 0rsquo are allundefined

A6 Bit-stringsVarious bit-string operation are defined over the type lsquobool listrsquo These are listed below

bit value middot ltmiddotgt bool listtimes nat rarr boolbit field middot ltmiddotmiddotgt bool listtimes nattimes nat rarr bool listconcatenation bool listtimes bool list rarr bool listduplication ^ bool listtimes nat rarr bool listaddition + bool listtimes bool list rarr bool listbitwise conjunction ampamp bool listtimes bool list rarr bool listbitwise disjunction || bool listtimes bool list rarr bool listbitwise exclusive-or bool listtimes bool list rarr bool listleft-shift ltlt bool listtimes nat rarr bool listright-shift gtgt+ bool listtimes nat rarr bool listrotate-right gtgt bool listtimes nat rarr bool list

The bit value operation gives the truth value of a bit-string at a given bit position for example

lsquo0s1101lt0gtrsquo = lsquotruersquo lsquo0s1101lt1gtrsquo = lsquofalsersquo lsquo0s1101lt2gtrsquo = lsquotruersquolsquo0s1101lt3gtrsquo = lsquotruersquo lsquo0s1101lt4gtrsquo = lsquofalsersquo lsquo0s1101lt5gtrsquo = lsquofalsersquo

25

The least-significant bit (position zero) occurs to the right of the bit-string The bit value oper-ation gives lsquofalsersquo when the bit position is greater than the size of the bit-string

The bit field operation extracts a range of bits from a bit-string For example

lsquo0s1101lt31gtrsquo = lsquo0s110rsquo and lsquo0s1101lt52gtrsquo = lsquo0s0011rsquo

In the bit-string expression xlthlgt the size of the result is always h + 1 minus l and the result isundefined when h lt l

Bit-string addition does not require the arguments to be of the same size and it gives anon-truncated result For example

lsquo0s101 + 0s1rsquo = lsquo0s110rsquo and lsquo0s101 + 0s11rsquo = lsquo0s1000rsquo

The operation ltlt performs a left-shift for example lsquo0s1101 ltlt 2rsquo = lsquo0s110100rsquo The oper-ation lsquorsquo is bit-string concatenation and lsquo^rsquo is duplication for example

lsquo0s101 0s11rsquo = lsquo0s10111rsquo and lsquo0s101 ^ 3rsquo = lsquo0s101101101rsquo

Regular list operations work as one would expect over bit-strings for example lsquoHead (0s101)rsquois a valid expression with value lsquotruersquo

A7 Characters and StringsThe following built-in functions are available for characters and strings

is alphabetic IsAlpha char rarr boolis alpha-numeric IsAlphaNum char rarr boolis decimal digit IsDigit char rarr boolis hexadecimal digit IsHexDigit char rarr boolis lowercase IsLower char rarr boolis uppercase IsUpper char rarr boolparse binary FromBinString string rarr num optionparse decimal FromDecString string rarr num optionparse hexadecimal FromHexString string rarr num optionconvert to lowercase ToLower string rarr stringconvert to uppercase ToUpper string rarr string

The following string operations are useful for parsing

split from the left splitl (char rarr bool) times string rarr string times stringsplit from the right splitr (char rarr bool) times string rarr string times stringsplit into fields fields (char rarr bool) times string rarr string listsplit into tokens tokens (char rarr bool) times string rarr string list

These are based on the SML functions Substringsplitl Substringsplitr Stringfieldsand Stringtokens Character predicates are declared using special syntax for example theexpression

splitl space or hexdigit and not in set a f ( 12bcab)

gives the result lsquo( 12bc ab)rsquo

26

A8 Floating-pointThe L3 language does not provide specialised types for representing floating-point numbersHowever 32-bit (single precision) and 64-bit (double precision) bit-vector values can be treatedas floating-point numbers the following IEEE compliant encoding formats are assumed

31 30 23 22 0

s e m1 8 23

63 62 52 51 0

s e m1 11 52

Here lsquosrsquo is the sign bit (set to lsquo1rsquo for negative numbers) lsquoersquo is a biased exponent value and lsquomrsquo is thesignificand The following constants and operations are available (where lsquofprsquo stands for bits(32)or bits(64) depending on the name of the operation)

rounding modes roundTiesToEvenroundTowardPositiveroundTowardNegativeroundTowardZero

ieee_rounding

flags (record) DivideByZero InvalidOpOverflow PrecisionUnderflow

ieee_flagsrarrbool

comparison values FP_LT FP_EQ FP_GT FP_UN ieee_compare

convert format FP32_ToFP64 fp32rarrfp64convert format FP64_ToFP32 ieee_roundingtimes fp64rarrfp32convert format FP64_ToFP32_ ieee_roundingtimes fp64rarr

ieee_flagstimes fp32from integer FP32|64_FromInt ieee_roundingtimes intrarrfpto integer FP32|64_ToInt ieee_roundingtimes fprarrint optionfrom string FP32|64 stringrarrfp

negative zero FP32|64_NegZero fppositive zero FP32|64_PosZero fpnegative infinity FP32|64_NegInf fppositive infinity FP32|64_PosInf fpa quiet NaN FP32|64_qNan fpa signalling NaN FP32|64_sNan fp

is integral FP32|64_IsIntegral fprarrboolis finite FP32|64_IsFinite fprarrboolis NaN FP32|64_IsNan fprarrboolis signalling NaN FP32|64_IsSignallingNan fprarrboolis normal FP32|64_IsNormal fprarrboolis sub-normal FP32|64_IsSubnormal fprarrboolis zero FP32|64_IsZero fprarrbool

27

comparison FP32|64_Compare fptimes fprarrieee_compareequality FP32|64_Equal fptimes fprarrboolless than FP32|64_LessThan fptimes fprarrboolless than or equal FP32|64_LessEqual fptimes fprarrboolgreater than FP32|64_GreaterThan fptimes fprarrboolgreater than or equal FP32|64_GreaterEqual fptimes fprarrbool

absolute FP32|64_Abs fprarrfpnegation FP32|64_Neg fprarrfpsquare root FP32|64_Sqrt ieee_roundingtimes fprarrfp(with flags) FP32|64_Sqrt_ ieee_roundingtimes fprarrieee_flagstimes fpaddition FP32|64_Add ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Add_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpsubtraction FP32|64_Sub ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Sub_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpmultiplication FP32|64_Mul ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Mul_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpfused multiply-add FP32|64_MulAdd ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulAdd_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpfused multiply-sub FP32|64_MulSub ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulSub_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpdivision FP32|64_Div ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Div_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fp

The L3 interpreter supports evaluation for 32-bit and 64-bit floating-point expressions but onlywhen running on an x86 machine that supports SSE2 extensions (Pentium 4 and later) Thefused multiply-addsub operations can only be interpreted on machines supporting the FMAextension which came in with the 4th generation (Haswell) Intel processors These restrictionsalso apply to any Standard ML code that is generated by L3

The IEEE 754 standard permits a number of different ways to flag underflow L3 predomi-nantly supports the x86 interpretation which detects underflow after rounding However whenexporting to HOL4 it is possible to choose detection before rounding which for example issuited to ARM instruction set models

A9 Miscellaneous operationsThe following operations are available

pair constructor αtimes β rarr αtimes βfirst of pair Fst αtimes β rarr αsecond of pair Snd αtimes β rarr β

casting [middot] α rarr βinitialise a map InitMap α rarr (βrarrα)

28

option constructor Some αrarrα optionoption projection ValOf α option rarr αoption test IsSome α option rarr bool

set membership in αtimesα set rarr boolset non-membership notin αtimesα set rarr boolset insertion insert αtimesα set rarrα setset union Union α settimesα set rarrα setset intersection Intersect α settimesα set rarrα setset difference Difference α settimesα set rarrα setset subset test IsSubset α settimesα set rarr boolset cardinality Cardinality α setrarr natset from a list SetOfList α list rarrα set

empty list Nil α listlist constructor Cons αtimesα list rarr α listlist head Head α list rarr αlist tail Tail α list rarr α listlist length Length α list rarr natlist concatenation α listtimesα list rarr α listlist flatten Concat α list list rarr α listlist element Element nattimesα list rarr αlist prefix Take nattimesα list rarr α listlist drop prefix Drop nattimesα list rarr α listlist pad left PadLeft αtimes nattimesα list rarr α listlist pad right PadRight αtimes nattimesα list rarr α listlist update Update αtimes nattimesα list rarr α listlist difference Remove α listtimesα list rarr α listlist intersection RemoveExcept α listtimesα list rarr α listlist without duplicates RemoveDuplicates α listrarr α listlist membership IsMember αtimesα list rarr boollist member position IndexOf αtimesα list rarr nat option

Sets are only defined over equality types see Appendix A2 The casting map is defined overcast-able types (as represented by the polymorphic type variables α and β) these are the primitivetypes (with the exception of lsquounitrsquo) and user defined enumerated types Assume lsquoEnumrsquo and lsquoEnum2rsquoare declared with

construct Enum One Two Three construct Enum2 Four Five Six Seven

The cast operations are described in Tables 1 to 7

29

Table 1 Cast to lsquoboolrsquo

From Operation Examples

bool identity lsquo[true]boolrsquo = lsquotruersquostring parse bool lsquo[true]boolrsquo = lsquotruersquo

lsquo[false]boolrsquo = lsquofalsersquootherwise undefined

nat is not zero lsquo[0n3]boolrsquo = lsquotruersquolsquo[0n0]boolrsquo = lsquofalsersquo

int is not zero lsquo[-0i1]boolrsquo = lsquotruersquolsquo[0i0]boolrsquo = lsquofalsersquo

bool list is not zero lsquo[0s11]boolrsquo = lsquotruersquolsquo[0s0]boolrsquo = lsquofalsersquo

bits(middot) is not zero lsquo[3`3]boolrsquo = lsquotruersquolsquo[0`3]boolrsquo = lsquofalsersquo

Enum is not the first element lsquo[One]boolrsquo = lsquofalsersquolsquo[Two]boolrsquo = lsquotruersquo

Table 2 Cast to lsquostringrsquo

From Operation Examples

bool name lsquo[true]stringrsquo = lsquotruersquostring identity lsquo[hello]stringrsquo = lsquohellorsquonat decimal lsquo[0n3]stringrsquo = lsquo3rsquoint signed decimal lsquo[-0i1]stringrsquo = lsquo~1rsquobool list binary lsquo[0s11]stringrsquo = lsquo11rsquobits(middot) unsigned hexadecimal lsquo[139`8]stringrsquo = lsquo8BrsquoEnum name lsquo[One]stringrsquo = lsquoOnersquo

30

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

Given the type declarations

construct enum One Two Three construct data

NoDataData1 string bits(8)Data2 enum bits(16)

the following illustrates a match expression

match y

case -1 NoData or -2 NoData =gt 0`4 -- note use of orcase _ Data1 (hello 11 x 11) =gt x + 1 -- use of bit-patterncase i Data2 (Three 1111 y) =gt [i] + ylt30gtcase 1 Data2 (_ 8) =gt 4case _ =gt 8

The body (right-hand side of lsquo=gtrsquo) of the first case line with a matching pattern is selected Thesymbol lsquo_rsquo is a wildcard and will match any value The lsquoorrsquo construct provides a shorthand forwriting blocks of clauses with differing patterns but the same body

The terms lsquo11 x 11rsquo and lsquo1111 yrsquo are called bit-patterns and they will match against a setof bit-vector values From the type declaration of lsquodatarsquo it is known that the variable lsquoxrsquo mustrepresent a 4-bit value because it occurs in the middle of an 8-bit word (the match requires bitslsquo11rsquo as a prefix and as a suffix) Likewise lsquoyrsquo must be a 12-bit value Multiple variables can occurin a bit-patterns for example lsquo1 x 1 y 0rsquo is a valid bit-pattern The type checker will oftenbe able to infer the type of pattern variables and if this fails type annotations can be added

The lsquopatternrsquo construct can help avoid situations where explicit annotations are repeatedlyrequired (causing clutter in patterns) If for example the variable lsquoimm5rsquo is frequently used tomatch a 5-bit value then the following declaration can be made

pattern imm5 bits(5)

In subsequent code the default type for pattern variable lsquoimm5rsquo will be lsquobits(5)rsquo The lsquopatternrsquoconstruct only influences type checking If a particular type hint is no longer appropriate thenit can be dropped for example one can insert the declaration lsquoclear pattern imm5rsquo

112 Defining Constants and OperationsUsers can construct operational semantics style formal specifications in L3 by defining their ownconstants and operations There is no module system or facility for local definitions all userdefinitions are made at the top-level with global scope User constants and operations cannot beoverloaded or redefined

A pure constant is a nullary (zero argument) operation that is state independent for examplethe following code declares a new constant

bits(32) UINT_MAX = 0xFFFFFFFF

10

The following code declares operations that are nullary but state dependent

declare number Natnat numberPlus1 = return (number + 1)unit incNumber = number lt- numberPlus1

Users can also declare new unary operations which may or may not be state dependent forexample

nat numberMinusN (nnat) = return (number + n) -- state dependentunit decNumber () = number lt- numberMinusN (1)nat mla (mnatnnatanat) = return (m n + a) -- pure

The operation lsquomlarsquo is unary because it takes a single triple as an argument To enhance clarityand avoid misunderstandards users may elect to specify nullary state dependent operations usinga single lsquounitrsquo argument Given the declarations above the expression lsquodecNumber()rsquo gives theclear impression that a call is being made (with possible side-effects) wheres the expressionlsquoincNumberrsquo does not

At the point of declaration operation arguments must be fully type annotated and onlymonomorphic types are allowed10 It is nevertheless possible to declare bit-vector operationsthat are valid with respect to some given set of bit widths for example the following are validdeclarations

--- valid for any bit-vector width N ---bits(N) bv_mla (mbits(N) nbits(N) abits(N)) = return (m n + a)

--- valid for sufficiently wide bit-vectors (N greater than eight) ---bool bit8 (xbits(N)) with N gt 8 = return (xlt8gt)

An L3 type error will arise if ever an application of the operation lsquobit8rsquo violates the bit widthconstraint Note that vector width variables (such as lsquoNnatrsquo above) can be used as if they werea regular variables in the definitional body of an operation

113 ComponentsWhen specifying instruction set architectures the two most significant programmerrsquos modelcomponents are typically the main memory and a collection of general purpose registers In theMIPS architecture for example there are thirty-two general purpose registers which may berepresented using the following map

declare gpr bits(5) -gt bits(64)

The statement

gpr(d) lt- gpr(r)10An compile time error will arise if the type checker is not able to infer all types the final definition must be

free of type variables

11

then expresses moving a value from register lsquorrsquo to register lsquodrsquo However register a memory accessis frequently more complicated than this in particular registers can be banked and memory canbe complex11 As such it is often necessary to specify collections of operations for accessing(reading and writing) these components With the MIPS example register zero is special (it isa constant value) and so one could define the following operations

bits(64) read_gpr (nbits(5)) = if n == 0 then 0 else gpr (n)unit write_gpr (vbits(64) nbits(5)) = when n ltgt 0 do gpr (n) lt- v

Thus the previous register transfers would now be specified as follows

write_gpr (read_gpr (n) d)

This precise style of specification is not entirely satisfying though since it departs in appearancefrom the pseudo code found in MIPS reference manuals The L3 language provides a specialmechanism for specifying a pair of operations that read and write state components With theMIPS example the following declaration can be made

component GPR (nbits(5)) bits(64)

value = if n == 0 then 0 else gpr(n)assign value = when n ltgt 0 do gpr(n) lt- value

One can then write

GPR(d) lt- GPR(r)

which is closer to the syntax used in the MIPS reference manuals The lsquocomponentrsquo constructeffectively provides a controlled form of operator overloading whereby the lsquoassignrsquo operation12

is select when the operator name appears on the left-hand side of an assignment (lsquolt-rsquo) and thelsquovaluersquo operation13 is applied otherwise Semantically these two operations are exactly the sameas the manually defined versions lsquowrite_gprrsquo and lsquoread_gprrsquo The ldquowriterdquo operation will alwayshave a lsquounitrsquo return type Users are free to specify the ldquoreadrdquo and ldquowriterdquo operations in any mannerthat they deem appropriate however the ldquowriterdquo operation cannot be defined recursively norcan the ldquoreadrdquo operation call the ldquowriterdquo operation

114 RecursionThe language permits the definition of recursive operations It is not possible to define mutuallyrecursive operations

The L3 language has been designed to act as an authoring front-end for the HOL4 theoremprover facilitating the task of writing instruction set specifications In order to successfullyimport an L3 specification it is necessary for the HOL4 system to prove that every user defined

11ARM registers are banked according to processor mode Memory can often be accessed with big- and little-endian byte ordering Special treatment may be needed for unaligned memory addresses for example when readinga 16-bit value from an odd address There may also be address translation (virtualisation) and memory hierarchies(caching)

12In this example the ldquowriterdquo operations is internally called lsquowriteGPRrsquo13Internally the ldquoreadrdquo operation is simply called lsquoGPRrsquo

12

operation is total (terminates on all inputs) If an L3 function is non-terminating then it willbe impossible to export that definition to HOL4 If a function is terminating but the standardautomation of HOL4 is unable to construct a termination proof then it may be necessary toprovide the prover with a hint in the form of a measure

Consider the following specification

declare m bits(8) -gt bits(8)

unit load (abits(8) lbits(8) list) =match l

case Nil =gt nothingcase Cons (h t) =gt m(a) lt- h load (a + 1 t)

The lsquoloadrsquo operation recurses over the list lsquolrsquo loading values into the map lsquomrsquo At the time ofwriting this documentation trying to build the exported HOL4 version of this specificationgives rise to the following error message

Initial goal

existRWF R andforallstate a l h t

(l = ht) rArrR ((a + 1wt)state with m = (a =+ h) statem) ((al)state)

Exception raised at TotalDefnDefinebetween beginning of frag 0 and end of frag 0at TotalDefndefnDefine

Unable to prove termination

Try using TotalDefntDefine ltnamegt ltquotationgt lttacgt

This occurs because HOL4 is unable to automatically prove that lsquoloadrsquo always terminates Toget around this problem the original L3 specification can be modified to contain an annotationas follows

unit load (abits(8) lbits(8) list) measure Length(l) =

The metadata lsquomeasure Length(l)rsquo tells HOL4 to examine the length of the list lsquolrsquo since thisvalue will decrease upon each recursive call to lsquoloadrsquo When the length of the list is zero (thelsquoNilrsquo case) there are no recursive calls so termination is guaranteed

The expression occurring after the lsquomeasurersquo keyword must be of type lsquonatrsquo After provid-ing a measure it is still possible that HOL4 will fail to prove termination either because thesupplied measure is incorrect or because the termination proof is non-trivial (requires humanguidance andor custom lemmas) If this occurs then users should either simplifyrewrite theirspecifications or if necessary report the problem

13

115 Instruction Set DefinitionsWhen working with instruction set models it is helpful to construct a datatype that representsthe set of machine (low-level) instructions This datatype constitutes a simple form of abstractsyntax tree (AST) and it can be used to build instruction decoders (identifying machine-codeinstructions and splitting opcodes into sub-fields) instruction encoders (generating opcodes fora given instruction) next-state functions (applying a semantics function for a given instruction)and assembly code parsers

By way of an example consider the MIPS instruction ANDI this instruction has the assemblycode syntax

ANDI rt rs immediate

and the following 32-bit machine-code encoding

31 26 25 21 20 16 15 0

001100 rs rt immediate6 5 5 16

The semantics of this instruction can be expressed with the operation

unit run_ANDI (rsbits(5) rtbits(5) immbits(16)) =GPR(rt) lt- GPR(rs) ampamp ZeroExtend (imm)

One could use this operation to directly specify a next-state function which would be of theform

unit Next =match Fetch -- fetches a 32-bit opcode from memory

middot middot middotcase 001100 rs rt imm =gt run_ANDI (rs rt imm)middot middot middot

This style of specification is direct and concise however it does lack some of the flexibility thatcomes with using an instruction datatype The L3 language provides support for an slightlydifferent style of specification This alternative approach is explained by first examining howone would specify things manually (explicitly) and then showing how L3 can streamline thisprocess

Firstly one could explicitly define an AST datatype for MIPS instructions it would be ofthe form

construct instruction

middot middot middotANDI bits(5) bits(5) bits(16)middot middot middot

14

This datatype provides a suitable constructor for the ANDI instruction It is now possible to definea decoder which maps opcodes onto AST entries for example

instruction Decode (opcbits(32)) =match opc

middot middot middotcase 001100 rs rt imm =gt ANDI (rs rt imm)middot middot middot

This decoder can be used to define our next-state function that is

unit Next = Run (Decode (Fetch))

where lsquoRunrsquo is defined by

unit Run (iinstruction) =match i

middot middot middotcase ANDI (args) =gt run_ANDI (args)middot middot middot

When working with full-scale architecture specifications (where the AST type is large) thereare some clear overheads associated with implementing this approach (in comparison with theAST free version) It becomes challenging to maintain the AST datatype declaration and tokeep it correctly synchronised with the instruction semantics operations (such as lsquorun_ANDIrsquo)and the definition of lsquoRunrsquo Note however that there is great uniformity in the AST datatypedeclaration and also in the definition of lsquoRunrsquo As such L3 is able to automatically define bothof these for the user

To make use of this automation the declaration of lsquorun_ANDIrsquo is simply modified to

define ANDI (rsbits(5) rtbits(5) immbits(16)) =GPR(rt) lt- GPR(rs) ampamp ZeroExtend (imm)

The lsquodefinersquo keyword tells L3 to define a semantics function14 (as before) and to also create anew lsquoinstructionrsquo datatype AST entry furthermore the two will be linked with the automaticconstruction of a lsquoRunrsquo function The lsquoinstructionrsquo type and lsquoRunrsquo function become defined (inscope) following the declaration lsquodefine Runrsquo After this declaration it is no longer possible touse the lsquodefinersquo construct again however it does become possible to define functions such aslsquoDecodersquo and lsquoNextrsquo

Specifications that are based on using lsquodefinersquo gain the benefits of declaring an instructionAST datatype without the downside of laborious coding overheads In the example above theoverhead amounts to one extra line of code this comes from defining a next-state function thatcalls the dedicated decode function followed by a call to lsquoRunrsquo

One of the key advantages of declaring an instruction datatype is that it makes it consider-ably easier to develop tools that work with assembly code syntax (performing parsing encoding

14This function is internally called lsquodfnANDIrsquo instead of lsquorun_ANDIrsquo

15

and pretty-printing) In this case it is relatively easy for example to map between the MIPSinstruction syntax andi $5 $6 1024 and the expression lsquoANDI (5 6 1024)rsquo Defining anencoder in L3 is relatively straightforward for example

bits(32) Encode (iinstruction) =match i

middot middot middotcase ANDI (rs rt imm) =gt 001100 rs rt immmiddot middot middot

Such a function can be used to write a MIPS assembler which would map the assembly codesyntax andi $5 $6 1024 onto the machine-code value 0x30c50400

2 TutorialThis section gives a brief overview of how to install and use L3

Installation The sources for L3 can be downloaded from the following webpage

wwwclcamacuk~acjf3l3

The file l3tarbz2 can be unpacked with the command

$ tar xvjf l3tarbz2

This will create a directory of the form L3-YYYY-MM-DD where the year month and day willcorrespond with the release date The current version of L3 depends upon PolyML 57 whichcan be obtained from the site polymlorg If PolyML is installed then L3 can be built as follows

$ cd L3-YYYY-MM-DD$ make

Once built the following should appear when you start L315

$ l3ltlt L3 gtgtgt

Users should consider running L3 with the command rlwrap l316

15This assumes that the directory L3-YYYY-MM-DDbin has been added to the PATH environment variable16Details on rlwrap utility can be found at the site freecodecomprojectsrlwrap

16

Basic Interaction The command prompt for L3 is essentially the read-eval-print loop (REPL)of PolyML As such users are free to write arbitrary Standard ML code The structure Runtimeenables interaction with L3 The following shows an arithmetic evaluation in Standard ML aswell as in the L3 interpreter (evalQ)

gt 1 + 2val it = 3 intgt RuntimeevalQ `0i1 + 2`val it = `0i3` Termterm

Various error messages can occur when using the interpreter for example

gt RuntimeevalQ `1 + 2`Exception- Fail Could not infer all types raised

gt RuntimeevalQ `0i2 div 0`Exception- Except (Div SOME (div (int [`0i2` `0i0`]))) raised

The first error occurs because unannotated number literals are regarded as bit-vector values andhere the vector width cannot be inferred

L3 declarations can be made using the function loadQ The following sequence shows thedeclaration and manipulation of a global variable

gt RuntimeloadQ `declare n nat`ltVARgt nval it = () unit

gt RuntimeevalQ `n`val it = `UNKNOWNnat` Termterm

gt RuntimeevalQ ` n lt- 3 n `val it = `0n3` Termterm

The global state can be examined using the function show for example

gt Runtimeshow()val it = [(n `0n3`)] Evalterm_stack

The state can be ldquowipedrdquo clean using the function reset and all declarations can be wiped usinglsquoresetAllrsquo for example

gt Runtimereset()val it = () unitgt Runtimeshow()val it = [(n `UNKNOWNnat`)] Evalterm_stack

gt RuntimeresetAll()val it = () unitgt Runtimeshow()val it = [] Evalterm_stack

The function lsquoLoadQrsquo is similar to lsquoloadQrsquo but it performs a lsquoresetAllrsquo before making declarations

17

Constants The structure Consts provides various functions for working with L3 constantsMany of the operation in the Consts structure will be of little interest to end-users however itcan be used to display some helpful information

The function ConstslookupConst can be used to lookup an operation for example

gt ConstslookupConst Log2val it = Primitive [(bits(a) -gt bits(a) -) (nat -gt nat -)] const

Since lsquoLog2rsquo is a primitive operation only the valid types (ordered by overload priority) are showWith user operations the internal representation (definition) of the operation will be shownfor example

gt RuntimeLoadQ `unit demo () = ()`gt ConstslookupConst demoval it = Definition (Abs ([(_ (unit -))] unit -gt unit `()`) NONE 1)

Constsconst

The functions ConstslistDefinitions and ConstslistExceptions provide details of all useroperations and exceptions respectively The function lsquoConstsstatsrsquo gives a summary of all thecurrent declarations

gt Constsstats()Primitives 188Destructors 5Constructors 0Accessors 0Exceptions 0User operations 1Instruction definitions 0

Here the constructors for primitive types (such as lsquoConsrsquo) are counted under ldquoprimitivesrdquo

Types The Types structure can be used to display information relating to L3 types In partic-ular this structure provides the functions TypeslookupConst and TypeslistConsts which aredemonstrated below

gt RuntimeloadQ `construct enum One Two Three`gt TypeslistConsts()val it =

[(enumeq = true ast = false def = Constructors (Enum ltdict(3)gt) num = 0)]

(string typeconst) list

gt TypeslookupConst intval it = SOME eq = true ast = false def = BaseType num = ~1

typeconst option

18

Loading and Exporting Specifications When writing an L3 specification it is expected thatuser declarations will be contained in an L3 source file A sample instruction set specification(tinyspec) can be found in the L3 distribution subdirectory examples This specification isbased on Thackerrsquos pedagogical Tiny 3 architecture it can be loaded as follows

gt RuntimeLoadF tinyspecLoading tinyspecltTYPgt regTltTYPgt wordTmiddot middot middotltFUNgt test_progDone

The string argument to the functions RuntimeloadF and RuntimeLoadF can be in the form ofa comma separated list of files which will be loaded in order That is the call

RuntimeloadF aspec bspec

will load aspec followed by bspecThe function HolExportexport will export the current L3 specification in the form of an

HOL4 script for example

gt HolExportexport tinyraiseexception okfunction okmiddot middot middotmextend skipmunextend skipCreated file tinyScriptsmlCreated file tinyLibsmlCreated file tinyLibsigDone

The function HolExportspec provides a convenient shortcut for performing LoadF and exportusing just a single call for example HolExportspec (tinyspec tiny) will perform theload and export presented above

L3 is capable of exporting two styles of HOL specification an explicitly monadic version(based on state_transformerTheory) and a version that directly manipulates state using let-expressions (which is the default style) For example a monadic version of the Tiny specifi-cation can be exported using the command HolExportspec (tinyspec tiny monadic)Other export options include sigdocs nosigdocs (for setting HOLrsquos TheoryPPinclude_docstrace variable) bigrecords nobigrecords (for controlling HOLrsquos Datatypebig_record_size)and underflowbefore nounderflowbefore (for selecting the required IEEE 754 underflow be-haviour)

Generated HOL4 specifications are not designed to be manually edited (or human readable)To build an L3 specification script the HOL library Import is needed This library is currentlylocated in the directory $HOL_DIRexamplesl3-machine-codecommon and so adding this path tothe INCLUDES variable of a local Holmakefile is recommended The examplesl3-machine-codedirectory contains various examples of using L3 generated specifications

19

Testing Specifications Having written an L3 specification it is fairly easy to write code (inStandard ML) that runs test vectors Code for running the tinyspec example can be found inthe file run-tinyspec In this test harness the Tiny state is initialised and a small test programis loaded simply by evaluating the expression lsquoinitialize (test_prog)rsquo

It is also possible to evaluate (run) models that have been exported to HOL4 The filerun-tinysml shows how this can be accomplished for the Tiny example

20

A Primitive Types and OperationsThe primitive types are as follows

unit bool char nat int bits(middot) rounding

There are two infix type constructors lsquorsquo for pairs and lsquo-gtrsquo for maps There are also postfix typeconstructors lsquosetrsquo lsquooptionrsquo and lsquolistrsquo for example sets of strings are represented by the typelsquostring setrsquo The following sections describe these primitive types together with some detailsof associated operations The following constants and operations are available

nullary () Nil None false roundTiesToEven roundTowardNegativeroundTowardPositive roundTowardZero true

prefix - ~ Abs Cardinality Cons Difference Drop Element FP32_AbsFP32_Add FP32_Equal FP32_IsNan FP32_LessThan FP32_MulFP32_Neg FP32_Sub FP64_Abs FP64_Add FP64_Equal FP64_IsNanFP64_LessThan FP64_Mul FP64_Neg FP64_Sub FromBinStringFromDecString FromHexString Fst Head IndexOf InitMapIntersection IsAlpha IsAlphaNum IsDigit IsHexDigit IsLowerIsMember IsSome IsSubset IsUpper Length Log2 Max Min MsbQuotRem Remove RemoveDuplicates RemoveExcept ReverseSetOfList SignExtend SignedMax SignedMin Size Snd Some TailTake ToLower ToUpper Union Update ValOf ZeroExtend not

infix = ampamp + - lt lt+ lt= lt=+ ltgt == gt gt+ gt= gt=+ ^ || gtgtltlt gtgt+ ltlt gtgt and div in insert mod notin or quot rem

sdivsmodother middot ltmiddotgt middot ltmiddotmiddotgt [middot] fields splitl splitr tokens

Many arithmetic operations are overloaded Unless otherwise stated the order of selection islsquobits(middot)rsquo lsquonatrsquo lsquointrsquo and then lsquobool listrsquo

A1 UnitThe type lsquounitrsquo represents the singleton set containing the value lsquo()rsquo The primary use of thistype is as the return type for procedures

A2 BoolThe type lsquoboolrsquo represents the two element set B = lsquotruersquo lsquofalsersquo The following standardBoolean operations are available

negation not bool rarr boolconjunction and booltimes bool rarr booldisjunction or booltimes bool rarr boolequality == αtimesα rarr boolnon-equality ltgt = αtimesα rarr bool

21

The infix operators lsquoandrsquo and lsquoorrsquo are interpreted with short-circuit evaluation for example in theexpression lsquofalse and f()rsquo the value of lsquof()rsquo is not computed as the overall expression will alwaysevaluate to false This short-circuiting influences the side-effects that occur during expressionevaluation

There are two prefix symbols for logical negation (these are semantically identical) with lsquorsquobinding slightly tighter than lsquonotrsquo This distinction is becomes significant when working withequalities for example lsquonot a == brsquo is taken to be not(a = b) whereas lsquoa == brsquo is (nota) = b

Equality is only defined with respect to equality types represented here by the type variableα An equality type is any type built without the used of the map operator lsquo-gtrsquo

A3 NatThe type lsquonatrsquo represents the natural numbers N = 0 1 2 The following operations areavailable

logarithm (base two) Log2 nat rarr natminimum value Min nattimes nat rarr natmaximium value Max nattimes nat rarr natless than lt nattimes nat rarr boolgreater than gt nattimes nat rarr boolless than or equal to lt= nattimes nat rarr boolgreater than or equal to gt= nattimes nat rarr booladdition + nattimes nat rarr natsubtraction - nattimes nat rarr natmultiplication nattimes nat rarr natexponentiation nattimes nat rarr natdivision div nattimes nat rarr natmodulus mod nattimes nat rarr nat

The lsquodivrsquo and lsquomodrsquo operations satisfy the following property

foralln 0 lt n =rArr forallk k = (k div n) lowast n+ (k mod n) and (k mod n) lt n

The expressions lsquoLog2(0)rsquo lsquox div 0rsquo and lsquox mod 0rsquo are all undefined 17

A4 IntThe type lsquointrsquo represents the integers Z = Ncupminus1minus2minus3 The following operations areavailable

17The interpreter will raise an exception when attempting to evaluate them

22

unary minus - int rarr intabsolute value Abs int rarr intminimum value Min inttimes int rarr intmaximum value Max inttimes int rarr intless than lt inttimes int rarr boolgreater than gt inttimes int rarr boolless than or equal to lt= inttimes int rarr boolgreater than or equal to gt= inttimes int rarr booladdition + inttimes int rarr intsubtraction - inttimes int rarr intmultiplication inttimes int rarr intexponentiation inttimes nat rarr intquotient and remainder QuotRem inttimes int rarr inttimes intquotient quot inttimes int rarr intremainder rem inttimes int rarr intdivision div inttimes int rarr intmodulus mod inttimes int rarr int

The operation lsquoAbsrsquo gives an positive integer value for example lsquoAbs(-2)rsquo = lsquo2rsquo The integeroperations lsquoquotrsquo and lsquodivrsquo are related to natural number division as follows

i quot j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

and

i div j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(minusi) div n(j))minus 1 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i and n(i) mod n(minusj) = 0

minus z(n(i) div n(minusj))minus 1 j lt 0 and 0 le i and n(i) mod n(minusj) = 0

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

where z NrarrZ and n ZrarrN are value preserving maps The lsquoremrsquo and lsquomodrsquo operations satisfythe equations

i rem j =

iminus (i quot j) lowast j j = 0

undefined j = 0i mod j =

iminus (i div j) lowast j j = 0

undefined j = 0

A5 Bit-vectorsThe type lsquobits(n)rsquo represents fixed-width (n-bit) words also known as bit-vectors for examplebits(32) is the type of 32-bit machine words18 The bits type can be viewed as representing

18These are called double-words (dword) in the x86 architecture and simply words in the ARM architecture

23

the set Zn = 0 1 2nminus1 for some 0 lt n At the type system level no distinction is madebetween signed and unsigned words however some operations (such as orderings) have signedand unsigned variants

The following bit-vector operations are available

1rsquos complement ~ bits(n) rarr bits(n)2rsquos complement - bits(n) rarr bits(n)absolute value Abs bits(n) rarr bits(n)logarithm (base two) Log2 bits(n) rarr bits(n)zero-extend ZeroExtend bits(m) rarr bits(n)sign-extend SignExtend bits(m) rarr bits(n)reverse bits Reverse bits(n) rarr bits(n)minimum value (u) Min bits(n)times bits(n) rarr bits(n)maximum value (u) Max bits(n)times bits(n) rarr bits(n)minimum value (s) SignedMin bits(n)times bits(n) rarr bits(n)maximum value (s) SignedMax bits(n)times bits(n) rarr bits(n)widthsize Size bits(n) rarr natmost-significant (sign) bit Msb bits(n) rarr boolbit value middot ltmiddotgt bits(n)times nat rarr boolbit field middot ltmiddotmiddotgt bits(m)times nattimes nat rarr bits(n)concatenation bits(m)times bits(n) rarr bits(p)duplication ^ bits(m)times nat rarr bits(n)less than (s) lt bits(n)times bits(n) rarr boolgreater than (s) gt bits(n)times bits(n) rarr boolless than or equal to (s) lt= bits(n)times bits(n) rarr boolgreater than or equal to (s) gt= bits(n)times bits(n) rarr boolless than (u) lt+ bits(n)times bits(n) rarr boolgreater than (u) gt+ bits(n)times bits(n) rarr boolless than or equal to (u) lt=+ bits(n)times bits(n) rarr boolgreater than or equal to (u) gt=+ bits(n)times bits(n) rarr booladdition + bits(n)times bits(n) rarr bits(n)subtraction - bits(n)times bits(n) rarr bits(n)multiplication bits(n)times bits(n) rarr bits(n)quotient (s) quot bits(n)times bits(n) rarr bits(n)remained (s) rem bits(n)times bits(n) rarr bits(n)division (u) div bits(n)times bits(n) rarr bits(n)modulus (u) mod bits(n)times bits(n) rarr bits(n)division (s) sdiv bits(n)times bits(n) rarr bits(n)modulus (s) smod bits(n)times bits(n) rarr bits(n)bitwise conjunction ampamp bits(n)times bits(n) rarr bits(n)bitwise disjunction || bits(n)times bits(n) rarr bits(n)bitwise exclusive-or bits(n)times bits(n) rarr bits(n)

Unsigned operations are labelled with (u) and signed operations are labelled with (s)The shift operations support shifting by either a bit-vector value or by a natural number value

The overloading is resolved such that the lsquonatrsquo variant is selected over the lsquobits(middot)rsquo version Theshift operations are

24

left-shift ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (u) gtgt+ bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (s) gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate left ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate right gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

A number of operations are undefined depending on the types of their domain and rangeThis is detailed in the following table

Operation Undefined when

ZeroExtend(x`n)`m m lt nSignExtend(x`n)`m m lt n(x`m)ltpgt m le p(x`m)lthlgt`n n = h+ 1minus l or h lt l orm le h((xm) (yn))`p p = m+ n((x`m) ^ n)`p p = m middot n (which covers n = 0)

The type checker will fail when these conditions are obviously violated Alternatively the inter-preter may raise a runtime error when these conditions are not met

As before the expressions lsquoLog2(0)rsquo lsquox quot 0rsquo lsquox rem 0rsquo lsquox div 0rsquo and lsquox mod 0rsquo are allundefined

A6 Bit-stringsVarious bit-string operation are defined over the type lsquobool listrsquo These are listed below

bit value middot ltmiddotgt bool listtimes nat rarr boolbit field middot ltmiddotmiddotgt bool listtimes nattimes nat rarr bool listconcatenation bool listtimes bool list rarr bool listduplication ^ bool listtimes nat rarr bool listaddition + bool listtimes bool list rarr bool listbitwise conjunction ampamp bool listtimes bool list rarr bool listbitwise disjunction || bool listtimes bool list rarr bool listbitwise exclusive-or bool listtimes bool list rarr bool listleft-shift ltlt bool listtimes nat rarr bool listright-shift gtgt+ bool listtimes nat rarr bool listrotate-right gtgt bool listtimes nat rarr bool list

The bit value operation gives the truth value of a bit-string at a given bit position for example

lsquo0s1101lt0gtrsquo = lsquotruersquo lsquo0s1101lt1gtrsquo = lsquofalsersquo lsquo0s1101lt2gtrsquo = lsquotruersquolsquo0s1101lt3gtrsquo = lsquotruersquo lsquo0s1101lt4gtrsquo = lsquofalsersquo lsquo0s1101lt5gtrsquo = lsquofalsersquo

25

The least-significant bit (position zero) occurs to the right of the bit-string The bit value oper-ation gives lsquofalsersquo when the bit position is greater than the size of the bit-string

The bit field operation extracts a range of bits from a bit-string For example

lsquo0s1101lt31gtrsquo = lsquo0s110rsquo and lsquo0s1101lt52gtrsquo = lsquo0s0011rsquo

In the bit-string expression xlthlgt the size of the result is always h + 1 minus l and the result isundefined when h lt l

Bit-string addition does not require the arguments to be of the same size and it gives anon-truncated result For example

lsquo0s101 + 0s1rsquo = lsquo0s110rsquo and lsquo0s101 + 0s11rsquo = lsquo0s1000rsquo

The operation ltlt performs a left-shift for example lsquo0s1101 ltlt 2rsquo = lsquo0s110100rsquo The oper-ation lsquorsquo is bit-string concatenation and lsquo^rsquo is duplication for example

lsquo0s101 0s11rsquo = lsquo0s10111rsquo and lsquo0s101 ^ 3rsquo = lsquo0s101101101rsquo

Regular list operations work as one would expect over bit-strings for example lsquoHead (0s101)rsquois a valid expression with value lsquotruersquo

A7 Characters and StringsThe following built-in functions are available for characters and strings

is alphabetic IsAlpha char rarr boolis alpha-numeric IsAlphaNum char rarr boolis decimal digit IsDigit char rarr boolis hexadecimal digit IsHexDigit char rarr boolis lowercase IsLower char rarr boolis uppercase IsUpper char rarr boolparse binary FromBinString string rarr num optionparse decimal FromDecString string rarr num optionparse hexadecimal FromHexString string rarr num optionconvert to lowercase ToLower string rarr stringconvert to uppercase ToUpper string rarr string

The following string operations are useful for parsing

split from the left splitl (char rarr bool) times string rarr string times stringsplit from the right splitr (char rarr bool) times string rarr string times stringsplit into fields fields (char rarr bool) times string rarr string listsplit into tokens tokens (char rarr bool) times string rarr string list

These are based on the SML functions Substringsplitl Substringsplitr Stringfieldsand Stringtokens Character predicates are declared using special syntax for example theexpression

splitl space or hexdigit and not in set a f ( 12bcab)

gives the result lsquo( 12bc ab)rsquo

26

A8 Floating-pointThe L3 language does not provide specialised types for representing floating-point numbersHowever 32-bit (single precision) and 64-bit (double precision) bit-vector values can be treatedas floating-point numbers the following IEEE compliant encoding formats are assumed

31 30 23 22 0

s e m1 8 23

63 62 52 51 0

s e m1 11 52

Here lsquosrsquo is the sign bit (set to lsquo1rsquo for negative numbers) lsquoersquo is a biased exponent value and lsquomrsquo is thesignificand The following constants and operations are available (where lsquofprsquo stands for bits(32)or bits(64) depending on the name of the operation)

rounding modes roundTiesToEvenroundTowardPositiveroundTowardNegativeroundTowardZero

ieee_rounding

flags (record) DivideByZero InvalidOpOverflow PrecisionUnderflow

ieee_flagsrarrbool

comparison values FP_LT FP_EQ FP_GT FP_UN ieee_compare

convert format FP32_ToFP64 fp32rarrfp64convert format FP64_ToFP32 ieee_roundingtimes fp64rarrfp32convert format FP64_ToFP32_ ieee_roundingtimes fp64rarr

ieee_flagstimes fp32from integer FP32|64_FromInt ieee_roundingtimes intrarrfpto integer FP32|64_ToInt ieee_roundingtimes fprarrint optionfrom string FP32|64 stringrarrfp

negative zero FP32|64_NegZero fppositive zero FP32|64_PosZero fpnegative infinity FP32|64_NegInf fppositive infinity FP32|64_PosInf fpa quiet NaN FP32|64_qNan fpa signalling NaN FP32|64_sNan fp

is integral FP32|64_IsIntegral fprarrboolis finite FP32|64_IsFinite fprarrboolis NaN FP32|64_IsNan fprarrboolis signalling NaN FP32|64_IsSignallingNan fprarrboolis normal FP32|64_IsNormal fprarrboolis sub-normal FP32|64_IsSubnormal fprarrboolis zero FP32|64_IsZero fprarrbool

27

comparison FP32|64_Compare fptimes fprarrieee_compareequality FP32|64_Equal fptimes fprarrboolless than FP32|64_LessThan fptimes fprarrboolless than or equal FP32|64_LessEqual fptimes fprarrboolgreater than FP32|64_GreaterThan fptimes fprarrboolgreater than or equal FP32|64_GreaterEqual fptimes fprarrbool

absolute FP32|64_Abs fprarrfpnegation FP32|64_Neg fprarrfpsquare root FP32|64_Sqrt ieee_roundingtimes fprarrfp(with flags) FP32|64_Sqrt_ ieee_roundingtimes fprarrieee_flagstimes fpaddition FP32|64_Add ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Add_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpsubtraction FP32|64_Sub ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Sub_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpmultiplication FP32|64_Mul ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Mul_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpfused multiply-add FP32|64_MulAdd ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulAdd_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpfused multiply-sub FP32|64_MulSub ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulSub_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpdivision FP32|64_Div ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Div_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fp

The L3 interpreter supports evaluation for 32-bit and 64-bit floating-point expressions but onlywhen running on an x86 machine that supports SSE2 extensions (Pentium 4 and later) Thefused multiply-addsub operations can only be interpreted on machines supporting the FMAextension which came in with the 4th generation (Haswell) Intel processors These restrictionsalso apply to any Standard ML code that is generated by L3

The IEEE 754 standard permits a number of different ways to flag underflow L3 predomi-nantly supports the x86 interpretation which detects underflow after rounding However whenexporting to HOL4 it is possible to choose detection before rounding which for example issuited to ARM instruction set models

A9 Miscellaneous operationsThe following operations are available

pair constructor αtimes β rarr αtimes βfirst of pair Fst αtimes β rarr αsecond of pair Snd αtimes β rarr β

casting [middot] α rarr βinitialise a map InitMap α rarr (βrarrα)

28

option constructor Some αrarrα optionoption projection ValOf α option rarr αoption test IsSome α option rarr bool

set membership in αtimesα set rarr boolset non-membership notin αtimesα set rarr boolset insertion insert αtimesα set rarrα setset union Union α settimesα set rarrα setset intersection Intersect α settimesα set rarrα setset difference Difference α settimesα set rarrα setset subset test IsSubset α settimesα set rarr boolset cardinality Cardinality α setrarr natset from a list SetOfList α list rarrα set

empty list Nil α listlist constructor Cons αtimesα list rarr α listlist head Head α list rarr αlist tail Tail α list rarr α listlist length Length α list rarr natlist concatenation α listtimesα list rarr α listlist flatten Concat α list list rarr α listlist element Element nattimesα list rarr αlist prefix Take nattimesα list rarr α listlist drop prefix Drop nattimesα list rarr α listlist pad left PadLeft αtimes nattimesα list rarr α listlist pad right PadRight αtimes nattimesα list rarr α listlist update Update αtimes nattimesα list rarr α listlist difference Remove α listtimesα list rarr α listlist intersection RemoveExcept α listtimesα list rarr α listlist without duplicates RemoveDuplicates α listrarr α listlist membership IsMember αtimesα list rarr boollist member position IndexOf αtimesα list rarr nat option

Sets are only defined over equality types see Appendix A2 The casting map is defined overcast-able types (as represented by the polymorphic type variables α and β) these are the primitivetypes (with the exception of lsquounitrsquo) and user defined enumerated types Assume lsquoEnumrsquo and lsquoEnum2rsquoare declared with

construct Enum One Two Three construct Enum2 Four Five Six Seven

The cast operations are described in Tables 1 to 7

29

Table 1 Cast to lsquoboolrsquo

From Operation Examples

bool identity lsquo[true]boolrsquo = lsquotruersquostring parse bool lsquo[true]boolrsquo = lsquotruersquo

lsquo[false]boolrsquo = lsquofalsersquootherwise undefined

nat is not zero lsquo[0n3]boolrsquo = lsquotruersquolsquo[0n0]boolrsquo = lsquofalsersquo

int is not zero lsquo[-0i1]boolrsquo = lsquotruersquolsquo[0i0]boolrsquo = lsquofalsersquo

bool list is not zero lsquo[0s11]boolrsquo = lsquotruersquolsquo[0s0]boolrsquo = lsquofalsersquo

bits(middot) is not zero lsquo[3`3]boolrsquo = lsquotruersquolsquo[0`3]boolrsquo = lsquofalsersquo

Enum is not the first element lsquo[One]boolrsquo = lsquofalsersquolsquo[Two]boolrsquo = lsquotruersquo

Table 2 Cast to lsquostringrsquo

From Operation Examples

bool name lsquo[true]stringrsquo = lsquotruersquostring identity lsquo[hello]stringrsquo = lsquohellorsquonat decimal lsquo[0n3]stringrsquo = lsquo3rsquoint signed decimal lsquo[-0i1]stringrsquo = lsquo~1rsquobool list binary lsquo[0s11]stringrsquo = lsquo11rsquobits(middot) unsigned hexadecimal lsquo[139`8]stringrsquo = lsquo8BrsquoEnum name lsquo[One]stringrsquo = lsquoOnersquo

30

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

The following code declares operations that are nullary but state dependent

declare number Natnat numberPlus1 = return (number + 1)unit incNumber = number lt- numberPlus1

Users can also declare new unary operations which may or may not be state dependent forexample

nat numberMinusN (nnat) = return (number + n) -- state dependentunit decNumber () = number lt- numberMinusN (1)nat mla (mnatnnatanat) = return (m n + a) -- pure

The operation lsquomlarsquo is unary because it takes a single triple as an argument To enhance clarityand avoid misunderstandards users may elect to specify nullary state dependent operations usinga single lsquounitrsquo argument Given the declarations above the expression lsquodecNumber()rsquo gives theclear impression that a call is being made (with possible side-effects) wheres the expressionlsquoincNumberrsquo does not

At the point of declaration operation arguments must be fully type annotated and onlymonomorphic types are allowed10 It is nevertheless possible to declare bit-vector operationsthat are valid with respect to some given set of bit widths for example the following are validdeclarations

--- valid for any bit-vector width N ---bits(N) bv_mla (mbits(N) nbits(N) abits(N)) = return (m n + a)

--- valid for sufficiently wide bit-vectors (N greater than eight) ---bool bit8 (xbits(N)) with N gt 8 = return (xlt8gt)

An L3 type error will arise if ever an application of the operation lsquobit8rsquo violates the bit widthconstraint Note that vector width variables (such as lsquoNnatrsquo above) can be used as if they werea regular variables in the definitional body of an operation

113 ComponentsWhen specifying instruction set architectures the two most significant programmerrsquos modelcomponents are typically the main memory and a collection of general purpose registers In theMIPS architecture for example there are thirty-two general purpose registers which may berepresented using the following map

declare gpr bits(5) -gt bits(64)

The statement

gpr(d) lt- gpr(r)10An compile time error will arise if the type checker is not able to infer all types the final definition must be

free of type variables

11

then expresses moving a value from register lsquorrsquo to register lsquodrsquo However register a memory accessis frequently more complicated than this in particular registers can be banked and memory canbe complex11 As such it is often necessary to specify collections of operations for accessing(reading and writing) these components With the MIPS example register zero is special (it isa constant value) and so one could define the following operations

bits(64) read_gpr (nbits(5)) = if n == 0 then 0 else gpr (n)unit write_gpr (vbits(64) nbits(5)) = when n ltgt 0 do gpr (n) lt- v

Thus the previous register transfers would now be specified as follows

write_gpr (read_gpr (n) d)

This precise style of specification is not entirely satisfying though since it departs in appearancefrom the pseudo code found in MIPS reference manuals The L3 language provides a specialmechanism for specifying a pair of operations that read and write state components With theMIPS example the following declaration can be made

component GPR (nbits(5)) bits(64)

value = if n == 0 then 0 else gpr(n)assign value = when n ltgt 0 do gpr(n) lt- value

One can then write

GPR(d) lt- GPR(r)

which is closer to the syntax used in the MIPS reference manuals The lsquocomponentrsquo constructeffectively provides a controlled form of operator overloading whereby the lsquoassignrsquo operation12

is select when the operator name appears on the left-hand side of an assignment (lsquolt-rsquo) and thelsquovaluersquo operation13 is applied otherwise Semantically these two operations are exactly the sameas the manually defined versions lsquowrite_gprrsquo and lsquoread_gprrsquo The ldquowriterdquo operation will alwayshave a lsquounitrsquo return type Users are free to specify the ldquoreadrdquo and ldquowriterdquo operations in any mannerthat they deem appropriate however the ldquowriterdquo operation cannot be defined recursively norcan the ldquoreadrdquo operation call the ldquowriterdquo operation

114 RecursionThe language permits the definition of recursive operations It is not possible to define mutuallyrecursive operations

The L3 language has been designed to act as an authoring front-end for the HOL4 theoremprover facilitating the task of writing instruction set specifications In order to successfullyimport an L3 specification it is necessary for the HOL4 system to prove that every user defined

11ARM registers are banked according to processor mode Memory can often be accessed with big- and little-endian byte ordering Special treatment may be needed for unaligned memory addresses for example when readinga 16-bit value from an odd address There may also be address translation (virtualisation) and memory hierarchies(caching)

12In this example the ldquowriterdquo operations is internally called lsquowriteGPRrsquo13Internally the ldquoreadrdquo operation is simply called lsquoGPRrsquo

12

operation is total (terminates on all inputs) If an L3 function is non-terminating then it willbe impossible to export that definition to HOL4 If a function is terminating but the standardautomation of HOL4 is unable to construct a termination proof then it may be necessary toprovide the prover with a hint in the form of a measure

Consider the following specification

declare m bits(8) -gt bits(8)

unit load (abits(8) lbits(8) list) =match l

case Nil =gt nothingcase Cons (h t) =gt m(a) lt- h load (a + 1 t)

The lsquoloadrsquo operation recurses over the list lsquolrsquo loading values into the map lsquomrsquo At the time ofwriting this documentation trying to build the exported HOL4 version of this specificationgives rise to the following error message

Initial goal

existRWF R andforallstate a l h t

(l = ht) rArrR ((a + 1wt)state with m = (a =+ h) statem) ((al)state)

Exception raised at TotalDefnDefinebetween beginning of frag 0 and end of frag 0at TotalDefndefnDefine

Unable to prove termination

Try using TotalDefntDefine ltnamegt ltquotationgt lttacgt

This occurs because HOL4 is unable to automatically prove that lsquoloadrsquo always terminates Toget around this problem the original L3 specification can be modified to contain an annotationas follows

unit load (abits(8) lbits(8) list) measure Length(l) =

The metadata lsquomeasure Length(l)rsquo tells HOL4 to examine the length of the list lsquolrsquo since thisvalue will decrease upon each recursive call to lsquoloadrsquo When the length of the list is zero (thelsquoNilrsquo case) there are no recursive calls so termination is guaranteed

The expression occurring after the lsquomeasurersquo keyword must be of type lsquonatrsquo After provid-ing a measure it is still possible that HOL4 will fail to prove termination either because thesupplied measure is incorrect or because the termination proof is non-trivial (requires humanguidance andor custom lemmas) If this occurs then users should either simplifyrewrite theirspecifications or if necessary report the problem

13

115 Instruction Set DefinitionsWhen working with instruction set models it is helpful to construct a datatype that representsthe set of machine (low-level) instructions This datatype constitutes a simple form of abstractsyntax tree (AST) and it can be used to build instruction decoders (identifying machine-codeinstructions and splitting opcodes into sub-fields) instruction encoders (generating opcodes fora given instruction) next-state functions (applying a semantics function for a given instruction)and assembly code parsers

By way of an example consider the MIPS instruction ANDI this instruction has the assemblycode syntax

ANDI rt rs immediate

and the following 32-bit machine-code encoding

31 26 25 21 20 16 15 0

001100 rs rt immediate6 5 5 16

The semantics of this instruction can be expressed with the operation

unit run_ANDI (rsbits(5) rtbits(5) immbits(16)) =GPR(rt) lt- GPR(rs) ampamp ZeroExtend (imm)

One could use this operation to directly specify a next-state function which would be of theform

unit Next =match Fetch -- fetches a 32-bit opcode from memory

middot middot middotcase 001100 rs rt imm =gt run_ANDI (rs rt imm)middot middot middot

This style of specification is direct and concise however it does lack some of the flexibility thatcomes with using an instruction datatype The L3 language provides support for an slightlydifferent style of specification This alternative approach is explained by first examining howone would specify things manually (explicitly) and then showing how L3 can streamline thisprocess

Firstly one could explicitly define an AST datatype for MIPS instructions it would be ofthe form

construct instruction

middot middot middotANDI bits(5) bits(5) bits(16)middot middot middot

14

This datatype provides a suitable constructor for the ANDI instruction It is now possible to definea decoder which maps opcodes onto AST entries for example

instruction Decode (opcbits(32)) =match opc

middot middot middotcase 001100 rs rt imm =gt ANDI (rs rt imm)middot middot middot

This decoder can be used to define our next-state function that is

unit Next = Run (Decode (Fetch))

where lsquoRunrsquo is defined by

unit Run (iinstruction) =match i

middot middot middotcase ANDI (args) =gt run_ANDI (args)middot middot middot

When working with full-scale architecture specifications (where the AST type is large) thereare some clear overheads associated with implementing this approach (in comparison with theAST free version) It becomes challenging to maintain the AST datatype declaration and tokeep it correctly synchronised with the instruction semantics operations (such as lsquorun_ANDIrsquo)and the definition of lsquoRunrsquo Note however that there is great uniformity in the AST datatypedeclaration and also in the definition of lsquoRunrsquo As such L3 is able to automatically define bothof these for the user

To make use of this automation the declaration of lsquorun_ANDIrsquo is simply modified to

define ANDI (rsbits(5) rtbits(5) immbits(16)) =GPR(rt) lt- GPR(rs) ampamp ZeroExtend (imm)

The lsquodefinersquo keyword tells L3 to define a semantics function14 (as before) and to also create anew lsquoinstructionrsquo datatype AST entry furthermore the two will be linked with the automaticconstruction of a lsquoRunrsquo function The lsquoinstructionrsquo type and lsquoRunrsquo function become defined (inscope) following the declaration lsquodefine Runrsquo After this declaration it is no longer possible touse the lsquodefinersquo construct again however it does become possible to define functions such aslsquoDecodersquo and lsquoNextrsquo

Specifications that are based on using lsquodefinersquo gain the benefits of declaring an instructionAST datatype without the downside of laborious coding overheads In the example above theoverhead amounts to one extra line of code this comes from defining a next-state function thatcalls the dedicated decode function followed by a call to lsquoRunrsquo

One of the key advantages of declaring an instruction datatype is that it makes it consider-ably easier to develop tools that work with assembly code syntax (performing parsing encoding

14This function is internally called lsquodfnANDIrsquo instead of lsquorun_ANDIrsquo

15

and pretty-printing) In this case it is relatively easy for example to map between the MIPSinstruction syntax andi $5 $6 1024 and the expression lsquoANDI (5 6 1024)rsquo Defining anencoder in L3 is relatively straightforward for example

bits(32) Encode (iinstruction) =match i

middot middot middotcase ANDI (rs rt imm) =gt 001100 rs rt immmiddot middot middot

Such a function can be used to write a MIPS assembler which would map the assembly codesyntax andi $5 $6 1024 onto the machine-code value 0x30c50400

2 TutorialThis section gives a brief overview of how to install and use L3

Installation The sources for L3 can be downloaded from the following webpage

wwwclcamacuk~acjf3l3

The file l3tarbz2 can be unpacked with the command

$ tar xvjf l3tarbz2

This will create a directory of the form L3-YYYY-MM-DD where the year month and day willcorrespond with the release date The current version of L3 depends upon PolyML 57 whichcan be obtained from the site polymlorg If PolyML is installed then L3 can be built as follows

$ cd L3-YYYY-MM-DD$ make

Once built the following should appear when you start L315

$ l3ltlt L3 gtgtgt

Users should consider running L3 with the command rlwrap l316

15This assumes that the directory L3-YYYY-MM-DDbin has been added to the PATH environment variable16Details on rlwrap utility can be found at the site freecodecomprojectsrlwrap

16

Basic Interaction The command prompt for L3 is essentially the read-eval-print loop (REPL)of PolyML As such users are free to write arbitrary Standard ML code The structure Runtimeenables interaction with L3 The following shows an arithmetic evaluation in Standard ML aswell as in the L3 interpreter (evalQ)

gt 1 + 2val it = 3 intgt RuntimeevalQ `0i1 + 2`val it = `0i3` Termterm

Various error messages can occur when using the interpreter for example

gt RuntimeevalQ `1 + 2`Exception- Fail Could not infer all types raised

gt RuntimeevalQ `0i2 div 0`Exception- Except (Div SOME (div (int [`0i2` `0i0`]))) raised

The first error occurs because unannotated number literals are regarded as bit-vector values andhere the vector width cannot be inferred

L3 declarations can be made using the function loadQ The following sequence shows thedeclaration and manipulation of a global variable

gt RuntimeloadQ `declare n nat`ltVARgt nval it = () unit

gt RuntimeevalQ `n`val it = `UNKNOWNnat` Termterm

gt RuntimeevalQ ` n lt- 3 n `val it = `0n3` Termterm

The global state can be examined using the function show for example

gt Runtimeshow()val it = [(n `0n3`)] Evalterm_stack

The state can be ldquowipedrdquo clean using the function reset and all declarations can be wiped usinglsquoresetAllrsquo for example

gt Runtimereset()val it = () unitgt Runtimeshow()val it = [(n `UNKNOWNnat`)] Evalterm_stack

gt RuntimeresetAll()val it = () unitgt Runtimeshow()val it = [] Evalterm_stack

The function lsquoLoadQrsquo is similar to lsquoloadQrsquo but it performs a lsquoresetAllrsquo before making declarations

17

Constants The structure Consts provides various functions for working with L3 constantsMany of the operation in the Consts structure will be of little interest to end-users however itcan be used to display some helpful information

The function ConstslookupConst can be used to lookup an operation for example

gt ConstslookupConst Log2val it = Primitive [(bits(a) -gt bits(a) -) (nat -gt nat -)] const

Since lsquoLog2rsquo is a primitive operation only the valid types (ordered by overload priority) are showWith user operations the internal representation (definition) of the operation will be shownfor example

gt RuntimeLoadQ `unit demo () = ()`gt ConstslookupConst demoval it = Definition (Abs ([(_ (unit -))] unit -gt unit `()`) NONE 1)

Constsconst

The functions ConstslistDefinitions and ConstslistExceptions provide details of all useroperations and exceptions respectively The function lsquoConstsstatsrsquo gives a summary of all thecurrent declarations

gt Constsstats()Primitives 188Destructors 5Constructors 0Accessors 0Exceptions 0User operations 1Instruction definitions 0

Here the constructors for primitive types (such as lsquoConsrsquo) are counted under ldquoprimitivesrdquo

Types The Types structure can be used to display information relating to L3 types In partic-ular this structure provides the functions TypeslookupConst and TypeslistConsts which aredemonstrated below

gt RuntimeloadQ `construct enum One Two Three`gt TypeslistConsts()val it =

[(enumeq = true ast = false def = Constructors (Enum ltdict(3)gt) num = 0)]

(string typeconst) list

gt TypeslookupConst intval it = SOME eq = true ast = false def = BaseType num = ~1

typeconst option

18

Loading and Exporting Specifications When writing an L3 specification it is expected thatuser declarations will be contained in an L3 source file A sample instruction set specification(tinyspec) can be found in the L3 distribution subdirectory examples This specification isbased on Thackerrsquos pedagogical Tiny 3 architecture it can be loaded as follows

gt RuntimeLoadF tinyspecLoading tinyspecltTYPgt regTltTYPgt wordTmiddot middot middotltFUNgt test_progDone

The string argument to the functions RuntimeloadF and RuntimeLoadF can be in the form ofa comma separated list of files which will be loaded in order That is the call

RuntimeloadF aspec bspec

will load aspec followed by bspecThe function HolExportexport will export the current L3 specification in the form of an

HOL4 script for example

gt HolExportexport tinyraiseexception okfunction okmiddot middot middotmextend skipmunextend skipCreated file tinyScriptsmlCreated file tinyLibsmlCreated file tinyLibsigDone

The function HolExportspec provides a convenient shortcut for performing LoadF and exportusing just a single call for example HolExportspec (tinyspec tiny) will perform theload and export presented above

L3 is capable of exporting two styles of HOL specification an explicitly monadic version(based on state_transformerTheory) and a version that directly manipulates state using let-expressions (which is the default style) For example a monadic version of the Tiny specifi-cation can be exported using the command HolExportspec (tinyspec tiny monadic)Other export options include sigdocs nosigdocs (for setting HOLrsquos TheoryPPinclude_docstrace variable) bigrecords nobigrecords (for controlling HOLrsquos Datatypebig_record_size)and underflowbefore nounderflowbefore (for selecting the required IEEE 754 underflow be-haviour)

Generated HOL4 specifications are not designed to be manually edited (or human readable)To build an L3 specification script the HOL library Import is needed This library is currentlylocated in the directory $HOL_DIRexamplesl3-machine-codecommon and so adding this path tothe INCLUDES variable of a local Holmakefile is recommended The examplesl3-machine-codedirectory contains various examples of using L3 generated specifications

19

Testing Specifications Having written an L3 specification it is fairly easy to write code (inStandard ML) that runs test vectors Code for running the tinyspec example can be found inthe file run-tinyspec In this test harness the Tiny state is initialised and a small test programis loaded simply by evaluating the expression lsquoinitialize (test_prog)rsquo

It is also possible to evaluate (run) models that have been exported to HOL4 The filerun-tinysml shows how this can be accomplished for the Tiny example

20

A Primitive Types and OperationsThe primitive types are as follows

unit bool char nat int bits(middot) rounding

There are two infix type constructors lsquorsquo for pairs and lsquo-gtrsquo for maps There are also postfix typeconstructors lsquosetrsquo lsquooptionrsquo and lsquolistrsquo for example sets of strings are represented by the typelsquostring setrsquo The following sections describe these primitive types together with some detailsof associated operations The following constants and operations are available

nullary () Nil None false roundTiesToEven roundTowardNegativeroundTowardPositive roundTowardZero true

prefix - ~ Abs Cardinality Cons Difference Drop Element FP32_AbsFP32_Add FP32_Equal FP32_IsNan FP32_LessThan FP32_MulFP32_Neg FP32_Sub FP64_Abs FP64_Add FP64_Equal FP64_IsNanFP64_LessThan FP64_Mul FP64_Neg FP64_Sub FromBinStringFromDecString FromHexString Fst Head IndexOf InitMapIntersection IsAlpha IsAlphaNum IsDigit IsHexDigit IsLowerIsMember IsSome IsSubset IsUpper Length Log2 Max Min MsbQuotRem Remove RemoveDuplicates RemoveExcept ReverseSetOfList SignExtend SignedMax SignedMin Size Snd Some TailTake ToLower ToUpper Union Update ValOf ZeroExtend not

infix = ampamp + - lt lt+ lt= lt=+ ltgt == gt gt+ gt= gt=+ ^ || gtgtltlt gtgt+ ltlt gtgt and div in insert mod notin or quot rem

sdivsmodother middot ltmiddotgt middot ltmiddotmiddotgt [middot] fields splitl splitr tokens

Many arithmetic operations are overloaded Unless otherwise stated the order of selection islsquobits(middot)rsquo lsquonatrsquo lsquointrsquo and then lsquobool listrsquo

A1 UnitThe type lsquounitrsquo represents the singleton set containing the value lsquo()rsquo The primary use of thistype is as the return type for procedures

A2 BoolThe type lsquoboolrsquo represents the two element set B = lsquotruersquo lsquofalsersquo The following standardBoolean operations are available

negation not bool rarr boolconjunction and booltimes bool rarr booldisjunction or booltimes bool rarr boolequality == αtimesα rarr boolnon-equality ltgt = αtimesα rarr bool

21

The infix operators lsquoandrsquo and lsquoorrsquo are interpreted with short-circuit evaluation for example in theexpression lsquofalse and f()rsquo the value of lsquof()rsquo is not computed as the overall expression will alwaysevaluate to false This short-circuiting influences the side-effects that occur during expressionevaluation

There are two prefix symbols for logical negation (these are semantically identical) with lsquorsquobinding slightly tighter than lsquonotrsquo This distinction is becomes significant when working withequalities for example lsquonot a == brsquo is taken to be not(a = b) whereas lsquoa == brsquo is (nota) = b

Equality is only defined with respect to equality types represented here by the type variableα An equality type is any type built without the used of the map operator lsquo-gtrsquo

A3 NatThe type lsquonatrsquo represents the natural numbers N = 0 1 2 The following operations areavailable

logarithm (base two) Log2 nat rarr natminimum value Min nattimes nat rarr natmaximium value Max nattimes nat rarr natless than lt nattimes nat rarr boolgreater than gt nattimes nat rarr boolless than or equal to lt= nattimes nat rarr boolgreater than or equal to gt= nattimes nat rarr booladdition + nattimes nat rarr natsubtraction - nattimes nat rarr natmultiplication nattimes nat rarr natexponentiation nattimes nat rarr natdivision div nattimes nat rarr natmodulus mod nattimes nat rarr nat

The lsquodivrsquo and lsquomodrsquo operations satisfy the following property

foralln 0 lt n =rArr forallk k = (k div n) lowast n+ (k mod n) and (k mod n) lt n

The expressions lsquoLog2(0)rsquo lsquox div 0rsquo and lsquox mod 0rsquo are all undefined 17

A4 IntThe type lsquointrsquo represents the integers Z = Ncupminus1minus2minus3 The following operations areavailable

17The interpreter will raise an exception when attempting to evaluate them

22

unary minus - int rarr intabsolute value Abs int rarr intminimum value Min inttimes int rarr intmaximum value Max inttimes int rarr intless than lt inttimes int rarr boolgreater than gt inttimes int rarr boolless than or equal to lt= inttimes int rarr boolgreater than or equal to gt= inttimes int rarr booladdition + inttimes int rarr intsubtraction - inttimes int rarr intmultiplication inttimes int rarr intexponentiation inttimes nat rarr intquotient and remainder QuotRem inttimes int rarr inttimes intquotient quot inttimes int rarr intremainder rem inttimes int rarr intdivision div inttimes int rarr intmodulus mod inttimes int rarr int

The operation lsquoAbsrsquo gives an positive integer value for example lsquoAbs(-2)rsquo = lsquo2rsquo The integeroperations lsquoquotrsquo and lsquodivrsquo are related to natural number division as follows

i quot j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

and

i div j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(minusi) div n(j))minus 1 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i and n(i) mod n(minusj) = 0

minus z(n(i) div n(minusj))minus 1 j lt 0 and 0 le i and n(i) mod n(minusj) = 0

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

where z NrarrZ and n ZrarrN are value preserving maps The lsquoremrsquo and lsquomodrsquo operations satisfythe equations

i rem j =

iminus (i quot j) lowast j j = 0

undefined j = 0i mod j =

iminus (i div j) lowast j j = 0

undefined j = 0

A5 Bit-vectorsThe type lsquobits(n)rsquo represents fixed-width (n-bit) words also known as bit-vectors for examplebits(32) is the type of 32-bit machine words18 The bits type can be viewed as representing

18These are called double-words (dword) in the x86 architecture and simply words in the ARM architecture

23

the set Zn = 0 1 2nminus1 for some 0 lt n At the type system level no distinction is madebetween signed and unsigned words however some operations (such as orderings) have signedand unsigned variants

The following bit-vector operations are available

1rsquos complement ~ bits(n) rarr bits(n)2rsquos complement - bits(n) rarr bits(n)absolute value Abs bits(n) rarr bits(n)logarithm (base two) Log2 bits(n) rarr bits(n)zero-extend ZeroExtend bits(m) rarr bits(n)sign-extend SignExtend bits(m) rarr bits(n)reverse bits Reverse bits(n) rarr bits(n)minimum value (u) Min bits(n)times bits(n) rarr bits(n)maximum value (u) Max bits(n)times bits(n) rarr bits(n)minimum value (s) SignedMin bits(n)times bits(n) rarr bits(n)maximum value (s) SignedMax bits(n)times bits(n) rarr bits(n)widthsize Size bits(n) rarr natmost-significant (sign) bit Msb bits(n) rarr boolbit value middot ltmiddotgt bits(n)times nat rarr boolbit field middot ltmiddotmiddotgt bits(m)times nattimes nat rarr bits(n)concatenation bits(m)times bits(n) rarr bits(p)duplication ^ bits(m)times nat rarr bits(n)less than (s) lt bits(n)times bits(n) rarr boolgreater than (s) gt bits(n)times bits(n) rarr boolless than or equal to (s) lt= bits(n)times bits(n) rarr boolgreater than or equal to (s) gt= bits(n)times bits(n) rarr boolless than (u) lt+ bits(n)times bits(n) rarr boolgreater than (u) gt+ bits(n)times bits(n) rarr boolless than or equal to (u) lt=+ bits(n)times bits(n) rarr boolgreater than or equal to (u) gt=+ bits(n)times bits(n) rarr booladdition + bits(n)times bits(n) rarr bits(n)subtraction - bits(n)times bits(n) rarr bits(n)multiplication bits(n)times bits(n) rarr bits(n)quotient (s) quot bits(n)times bits(n) rarr bits(n)remained (s) rem bits(n)times bits(n) rarr bits(n)division (u) div bits(n)times bits(n) rarr bits(n)modulus (u) mod bits(n)times bits(n) rarr bits(n)division (s) sdiv bits(n)times bits(n) rarr bits(n)modulus (s) smod bits(n)times bits(n) rarr bits(n)bitwise conjunction ampamp bits(n)times bits(n) rarr bits(n)bitwise disjunction || bits(n)times bits(n) rarr bits(n)bitwise exclusive-or bits(n)times bits(n) rarr bits(n)

Unsigned operations are labelled with (u) and signed operations are labelled with (s)The shift operations support shifting by either a bit-vector value or by a natural number value

The overloading is resolved such that the lsquonatrsquo variant is selected over the lsquobits(middot)rsquo version Theshift operations are

24

left-shift ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (u) gtgt+ bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (s) gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate left ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate right gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

A number of operations are undefined depending on the types of their domain and rangeThis is detailed in the following table

Operation Undefined when

ZeroExtend(x`n)`m m lt nSignExtend(x`n)`m m lt n(x`m)ltpgt m le p(x`m)lthlgt`n n = h+ 1minus l or h lt l orm le h((xm) (yn))`p p = m+ n((x`m) ^ n)`p p = m middot n (which covers n = 0)

The type checker will fail when these conditions are obviously violated Alternatively the inter-preter may raise a runtime error when these conditions are not met

As before the expressions lsquoLog2(0)rsquo lsquox quot 0rsquo lsquox rem 0rsquo lsquox div 0rsquo and lsquox mod 0rsquo are allundefined

A6 Bit-stringsVarious bit-string operation are defined over the type lsquobool listrsquo These are listed below

bit value middot ltmiddotgt bool listtimes nat rarr boolbit field middot ltmiddotmiddotgt bool listtimes nattimes nat rarr bool listconcatenation bool listtimes bool list rarr bool listduplication ^ bool listtimes nat rarr bool listaddition + bool listtimes bool list rarr bool listbitwise conjunction ampamp bool listtimes bool list rarr bool listbitwise disjunction || bool listtimes bool list rarr bool listbitwise exclusive-or bool listtimes bool list rarr bool listleft-shift ltlt bool listtimes nat rarr bool listright-shift gtgt+ bool listtimes nat rarr bool listrotate-right gtgt bool listtimes nat rarr bool list

The bit value operation gives the truth value of a bit-string at a given bit position for example

lsquo0s1101lt0gtrsquo = lsquotruersquo lsquo0s1101lt1gtrsquo = lsquofalsersquo lsquo0s1101lt2gtrsquo = lsquotruersquolsquo0s1101lt3gtrsquo = lsquotruersquo lsquo0s1101lt4gtrsquo = lsquofalsersquo lsquo0s1101lt5gtrsquo = lsquofalsersquo

25

The least-significant bit (position zero) occurs to the right of the bit-string The bit value oper-ation gives lsquofalsersquo when the bit position is greater than the size of the bit-string

The bit field operation extracts a range of bits from a bit-string For example

lsquo0s1101lt31gtrsquo = lsquo0s110rsquo and lsquo0s1101lt52gtrsquo = lsquo0s0011rsquo

In the bit-string expression xlthlgt the size of the result is always h + 1 minus l and the result isundefined when h lt l

Bit-string addition does not require the arguments to be of the same size and it gives anon-truncated result For example

lsquo0s101 + 0s1rsquo = lsquo0s110rsquo and lsquo0s101 + 0s11rsquo = lsquo0s1000rsquo

The operation ltlt performs a left-shift for example lsquo0s1101 ltlt 2rsquo = lsquo0s110100rsquo The oper-ation lsquorsquo is bit-string concatenation and lsquo^rsquo is duplication for example

lsquo0s101 0s11rsquo = lsquo0s10111rsquo and lsquo0s101 ^ 3rsquo = lsquo0s101101101rsquo

Regular list operations work as one would expect over bit-strings for example lsquoHead (0s101)rsquois a valid expression with value lsquotruersquo

A7 Characters and StringsThe following built-in functions are available for characters and strings

is alphabetic IsAlpha char rarr boolis alpha-numeric IsAlphaNum char rarr boolis decimal digit IsDigit char rarr boolis hexadecimal digit IsHexDigit char rarr boolis lowercase IsLower char rarr boolis uppercase IsUpper char rarr boolparse binary FromBinString string rarr num optionparse decimal FromDecString string rarr num optionparse hexadecimal FromHexString string rarr num optionconvert to lowercase ToLower string rarr stringconvert to uppercase ToUpper string rarr string

The following string operations are useful for parsing

split from the left splitl (char rarr bool) times string rarr string times stringsplit from the right splitr (char rarr bool) times string rarr string times stringsplit into fields fields (char rarr bool) times string rarr string listsplit into tokens tokens (char rarr bool) times string rarr string list

These are based on the SML functions Substringsplitl Substringsplitr Stringfieldsand Stringtokens Character predicates are declared using special syntax for example theexpression

splitl space or hexdigit and not in set a f ( 12bcab)

gives the result lsquo( 12bc ab)rsquo

26

A8 Floating-pointThe L3 language does not provide specialised types for representing floating-point numbersHowever 32-bit (single precision) and 64-bit (double precision) bit-vector values can be treatedas floating-point numbers the following IEEE compliant encoding formats are assumed

31 30 23 22 0

s e m1 8 23

63 62 52 51 0

s e m1 11 52

Here lsquosrsquo is the sign bit (set to lsquo1rsquo for negative numbers) lsquoersquo is a biased exponent value and lsquomrsquo is thesignificand The following constants and operations are available (where lsquofprsquo stands for bits(32)or bits(64) depending on the name of the operation)

rounding modes roundTiesToEvenroundTowardPositiveroundTowardNegativeroundTowardZero

ieee_rounding

flags (record) DivideByZero InvalidOpOverflow PrecisionUnderflow

ieee_flagsrarrbool

comparison values FP_LT FP_EQ FP_GT FP_UN ieee_compare

convert format FP32_ToFP64 fp32rarrfp64convert format FP64_ToFP32 ieee_roundingtimes fp64rarrfp32convert format FP64_ToFP32_ ieee_roundingtimes fp64rarr

ieee_flagstimes fp32from integer FP32|64_FromInt ieee_roundingtimes intrarrfpto integer FP32|64_ToInt ieee_roundingtimes fprarrint optionfrom string FP32|64 stringrarrfp

negative zero FP32|64_NegZero fppositive zero FP32|64_PosZero fpnegative infinity FP32|64_NegInf fppositive infinity FP32|64_PosInf fpa quiet NaN FP32|64_qNan fpa signalling NaN FP32|64_sNan fp

is integral FP32|64_IsIntegral fprarrboolis finite FP32|64_IsFinite fprarrboolis NaN FP32|64_IsNan fprarrboolis signalling NaN FP32|64_IsSignallingNan fprarrboolis normal FP32|64_IsNormal fprarrboolis sub-normal FP32|64_IsSubnormal fprarrboolis zero FP32|64_IsZero fprarrbool

27

comparison FP32|64_Compare fptimes fprarrieee_compareequality FP32|64_Equal fptimes fprarrboolless than FP32|64_LessThan fptimes fprarrboolless than or equal FP32|64_LessEqual fptimes fprarrboolgreater than FP32|64_GreaterThan fptimes fprarrboolgreater than or equal FP32|64_GreaterEqual fptimes fprarrbool

absolute FP32|64_Abs fprarrfpnegation FP32|64_Neg fprarrfpsquare root FP32|64_Sqrt ieee_roundingtimes fprarrfp(with flags) FP32|64_Sqrt_ ieee_roundingtimes fprarrieee_flagstimes fpaddition FP32|64_Add ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Add_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpsubtraction FP32|64_Sub ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Sub_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpmultiplication FP32|64_Mul ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Mul_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpfused multiply-add FP32|64_MulAdd ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulAdd_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpfused multiply-sub FP32|64_MulSub ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulSub_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpdivision FP32|64_Div ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Div_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fp

The L3 interpreter supports evaluation for 32-bit and 64-bit floating-point expressions but onlywhen running on an x86 machine that supports SSE2 extensions (Pentium 4 and later) Thefused multiply-addsub operations can only be interpreted on machines supporting the FMAextension which came in with the 4th generation (Haswell) Intel processors These restrictionsalso apply to any Standard ML code that is generated by L3

The IEEE 754 standard permits a number of different ways to flag underflow L3 predomi-nantly supports the x86 interpretation which detects underflow after rounding However whenexporting to HOL4 it is possible to choose detection before rounding which for example issuited to ARM instruction set models

A9 Miscellaneous operationsThe following operations are available

pair constructor αtimes β rarr αtimes βfirst of pair Fst αtimes β rarr αsecond of pair Snd αtimes β rarr β

casting [middot] α rarr βinitialise a map InitMap α rarr (βrarrα)

28

option constructor Some αrarrα optionoption projection ValOf α option rarr αoption test IsSome α option rarr bool

set membership in αtimesα set rarr boolset non-membership notin αtimesα set rarr boolset insertion insert αtimesα set rarrα setset union Union α settimesα set rarrα setset intersection Intersect α settimesα set rarrα setset difference Difference α settimesα set rarrα setset subset test IsSubset α settimesα set rarr boolset cardinality Cardinality α setrarr natset from a list SetOfList α list rarrα set

empty list Nil α listlist constructor Cons αtimesα list rarr α listlist head Head α list rarr αlist tail Tail α list rarr α listlist length Length α list rarr natlist concatenation α listtimesα list rarr α listlist flatten Concat α list list rarr α listlist element Element nattimesα list rarr αlist prefix Take nattimesα list rarr α listlist drop prefix Drop nattimesα list rarr α listlist pad left PadLeft αtimes nattimesα list rarr α listlist pad right PadRight αtimes nattimesα list rarr α listlist update Update αtimes nattimesα list rarr α listlist difference Remove α listtimesα list rarr α listlist intersection RemoveExcept α listtimesα list rarr α listlist without duplicates RemoveDuplicates α listrarr α listlist membership IsMember αtimesα list rarr boollist member position IndexOf αtimesα list rarr nat option

Sets are only defined over equality types see Appendix A2 The casting map is defined overcast-able types (as represented by the polymorphic type variables α and β) these are the primitivetypes (with the exception of lsquounitrsquo) and user defined enumerated types Assume lsquoEnumrsquo and lsquoEnum2rsquoare declared with

construct Enum One Two Three construct Enum2 Four Five Six Seven

The cast operations are described in Tables 1 to 7

29

Table 1 Cast to lsquoboolrsquo

From Operation Examples

bool identity lsquo[true]boolrsquo = lsquotruersquostring parse bool lsquo[true]boolrsquo = lsquotruersquo

lsquo[false]boolrsquo = lsquofalsersquootherwise undefined

nat is not zero lsquo[0n3]boolrsquo = lsquotruersquolsquo[0n0]boolrsquo = lsquofalsersquo

int is not zero lsquo[-0i1]boolrsquo = lsquotruersquolsquo[0i0]boolrsquo = lsquofalsersquo

bool list is not zero lsquo[0s11]boolrsquo = lsquotruersquolsquo[0s0]boolrsquo = lsquofalsersquo

bits(middot) is not zero lsquo[3`3]boolrsquo = lsquotruersquolsquo[0`3]boolrsquo = lsquofalsersquo

Enum is not the first element lsquo[One]boolrsquo = lsquofalsersquolsquo[Two]boolrsquo = lsquotruersquo

Table 2 Cast to lsquostringrsquo

From Operation Examples

bool name lsquo[true]stringrsquo = lsquotruersquostring identity lsquo[hello]stringrsquo = lsquohellorsquonat decimal lsquo[0n3]stringrsquo = lsquo3rsquoint signed decimal lsquo[-0i1]stringrsquo = lsquo~1rsquobool list binary lsquo[0s11]stringrsquo = lsquo11rsquobits(middot) unsigned hexadecimal lsquo[139`8]stringrsquo = lsquo8BrsquoEnum name lsquo[One]stringrsquo = lsquoOnersquo

30

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

then expresses moving a value from register lsquorrsquo to register lsquodrsquo However register a memory accessis frequently more complicated than this in particular registers can be banked and memory canbe complex11 As such it is often necessary to specify collections of operations for accessing(reading and writing) these components With the MIPS example register zero is special (it isa constant value) and so one could define the following operations

bits(64) read_gpr (nbits(5)) = if n == 0 then 0 else gpr (n)unit write_gpr (vbits(64) nbits(5)) = when n ltgt 0 do gpr (n) lt- v

Thus the previous register transfers would now be specified as follows

write_gpr (read_gpr (n) d)

This precise style of specification is not entirely satisfying though since it departs in appearancefrom the pseudo code found in MIPS reference manuals The L3 language provides a specialmechanism for specifying a pair of operations that read and write state components With theMIPS example the following declaration can be made

component GPR (nbits(5)) bits(64)

value = if n == 0 then 0 else gpr(n)assign value = when n ltgt 0 do gpr(n) lt- value

One can then write

GPR(d) lt- GPR(r)

which is closer to the syntax used in the MIPS reference manuals The lsquocomponentrsquo constructeffectively provides a controlled form of operator overloading whereby the lsquoassignrsquo operation12

is select when the operator name appears on the left-hand side of an assignment (lsquolt-rsquo) and thelsquovaluersquo operation13 is applied otherwise Semantically these two operations are exactly the sameas the manually defined versions lsquowrite_gprrsquo and lsquoread_gprrsquo The ldquowriterdquo operation will alwayshave a lsquounitrsquo return type Users are free to specify the ldquoreadrdquo and ldquowriterdquo operations in any mannerthat they deem appropriate however the ldquowriterdquo operation cannot be defined recursively norcan the ldquoreadrdquo operation call the ldquowriterdquo operation

114 RecursionThe language permits the definition of recursive operations It is not possible to define mutuallyrecursive operations

The L3 language has been designed to act as an authoring front-end for the HOL4 theoremprover facilitating the task of writing instruction set specifications In order to successfullyimport an L3 specification it is necessary for the HOL4 system to prove that every user defined

11ARM registers are banked according to processor mode Memory can often be accessed with big- and little-endian byte ordering Special treatment may be needed for unaligned memory addresses for example when readinga 16-bit value from an odd address There may also be address translation (virtualisation) and memory hierarchies(caching)

12In this example the ldquowriterdquo operations is internally called lsquowriteGPRrsquo13Internally the ldquoreadrdquo operation is simply called lsquoGPRrsquo

12

operation is total (terminates on all inputs) If an L3 function is non-terminating then it willbe impossible to export that definition to HOL4 If a function is terminating but the standardautomation of HOL4 is unable to construct a termination proof then it may be necessary toprovide the prover with a hint in the form of a measure

Consider the following specification

declare m bits(8) -gt bits(8)

unit load (abits(8) lbits(8) list) =match l

case Nil =gt nothingcase Cons (h t) =gt m(a) lt- h load (a + 1 t)

The lsquoloadrsquo operation recurses over the list lsquolrsquo loading values into the map lsquomrsquo At the time ofwriting this documentation trying to build the exported HOL4 version of this specificationgives rise to the following error message

Initial goal

existRWF R andforallstate a l h t

(l = ht) rArrR ((a + 1wt)state with m = (a =+ h) statem) ((al)state)

Exception raised at TotalDefnDefinebetween beginning of frag 0 and end of frag 0at TotalDefndefnDefine

Unable to prove termination

Try using TotalDefntDefine ltnamegt ltquotationgt lttacgt

This occurs because HOL4 is unable to automatically prove that lsquoloadrsquo always terminates Toget around this problem the original L3 specification can be modified to contain an annotationas follows

unit load (abits(8) lbits(8) list) measure Length(l) =

The metadata lsquomeasure Length(l)rsquo tells HOL4 to examine the length of the list lsquolrsquo since thisvalue will decrease upon each recursive call to lsquoloadrsquo When the length of the list is zero (thelsquoNilrsquo case) there are no recursive calls so termination is guaranteed

The expression occurring after the lsquomeasurersquo keyword must be of type lsquonatrsquo After provid-ing a measure it is still possible that HOL4 will fail to prove termination either because thesupplied measure is incorrect or because the termination proof is non-trivial (requires humanguidance andor custom lemmas) If this occurs then users should either simplifyrewrite theirspecifications or if necessary report the problem

13

115 Instruction Set DefinitionsWhen working with instruction set models it is helpful to construct a datatype that representsthe set of machine (low-level) instructions This datatype constitutes a simple form of abstractsyntax tree (AST) and it can be used to build instruction decoders (identifying machine-codeinstructions and splitting opcodes into sub-fields) instruction encoders (generating opcodes fora given instruction) next-state functions (applying a semantics function for a given instruction)and assembly code parsers

By way of an example consider the MIPS instruction ANDI this instruction has the assemblycode syntax

ANDI rt rs immediate

and the following 32-bit machine-code encoding

31 26 25 21 20 16 15 0

001100 rs rt immediate6 5 5 16

The semantics of this instruction can be expressed with the operation

unit run_ANDI (rsbits(5) rtbits(5) immbits(16)) =GPR(rt) lt- GPR(rs) ampamp ZeroExtend (imm)

One could use this operation to directly specify a next-state function which would be of theform

unit Next =match Fetch -- fetches a 32-bit opcode from memory

middot middot middotcase 001100 rs rt imm =gt run_ANDI (rs rt imm)middot middot middot

This style of specification is direct and concise however it does lack some of the flexibility thatcomes with using an instruction datatype The L3 language provides support for an slightlydifferent style of specification This alternative approach is explained by first examining howone would specify things manually (explicitly) and then showing how L3 can streamline thisprocess

Firstly one could explicitly define an AST datatype for MIPS instructions it would be ofthe form

construct instruction

middot middot middotANDI bits(5) bits(5) bits(16)middot middot middot

14

This datatype provides a suitable constructor for the ANDI instruction It is now possible to definea decoder which maps opcodes onto AST entries for example

instruction Decode (opcbits(32)) =match opc

middot middot middotcase 001100 rs rt imm =gt ANDI (rs rt imm)middot middot middot

This decoder can be used to define our next-state function that is

unit Next = Run (Decode (Fetch))

where lsquoRunrsquo is defined by

unit Run (iinstruction) =match i

middot middot middotcase ANDI (args) =gt run_ANDI (args)middot middot middot

When working with full-scale architecture specifications (where the AST type is large) thereare some clear overheads associated with implementing this approach (in comparison with theAST free version) It becomes challenging to maintain the AST datatype declaration and tokeep it correctly synchronised with the instruction semantics operations (such as lsquorun_ANDIrsquo)and the definition of lsquoRunrsquo Note however that there is great uniformity in the AST datatypedeclaration and also in the definition of lsquoRunrsquo As such L3 is able to automatically define bothof these for the user

To make use of this automation the declaration of lsquorun_ANDIrsquo is simply modified to

define ANDI (rsbits(5) rtbits(5) immbits(16)) =GPR(rt) lt- GPR(rs) ampamp ZeroExtend (imm)

The lsquodefinersquo keyword tells L3 to define a semantics function14 (as before) and to also create anew lsquoinstructionrsquo datatype AST entry furthermore the two will be linked with the automaticconstruction of a lsquoRunrsquo function The lsquoinstructionrsquo type and lsquoRunrsquo function become defined (inscope) following the declaration lsquodefine Runrsquo After this declaration it is no longer possible touse the lsquodefinersquo construct again however it does become possible to define functions such aslsquoDecodersquo and lsquoNextrsquo

Specifications that are based on using lsquodefinersquo gain the benefits of declaring an instructionAST datatype without the downside of laborious coding overheads In the example above theoverhead amounts to one extra line of code this comes from defining a next-state function thatcalls the dedicated decode function followed by a call to lsquoRunrsquo

One of the key advantages of declaring an instruction datatype is that it makes it consider-ably easier to develop tools that work with assembly code syntax (performing parsing encoding

14This function is internally called lsquodfnANDIrsquo instead of lsquorun_ANDIrsquo

15

and pretty-printing) In this case it is relatively easy for example to map between the MIPSinstruction syntax andi $5 $6 1024 and the expression lsquoANDI (5 6 1024)rsquo Defining anencoder in L3 is relatively straightforward for example

bits(32) Encode (iinstruction) =match i

middot middot middotcase ANDI (rs rt imm) =gt 001100 rs rt immmiddot middot middot

Such a function can be used to write a MIPS assembler which would map the assembly codesyntax andi $5 $6 1024 onto the machine-code value 0x30c50400

2 TutorialThis section gives a brief overview of how to install and use L3

Installation The sources for L3 can be downloaded from the following webpage

wwwclcamacuk~acjf3l3

The file l3tarbz2 can be unpacked with the command

$ tar xvjf l3tarbz2

This will create a directory of the form L3-YYYY-MM-DD where the year month and day willcorrespond with the release date The current version of L3 depends upon PolyML 57 whichcan be obtained from the site polymlorg If PolyML is installed then L3 can be built as follows

$ cd L3-YYYY-MM-DD$ make

Once built the following should appear when you start L315

$ l3ltlt L3 gtgtgt

Users should consider running L3 with the command rlwrap l316

15This assumes that the directory L3-YYYY-MM-DDbin has been added to the PATH environment variable16Details on rlwrap utility can be found at the site freecodecomprojectsrlwrap

16

Basic Interaction The command prompt for L3 is essentially the read-eval-print loop (REPL)of PolyML As such users are free to write arbitrary Standard ML code The structure Runtimeenables interaction with L3 The following shows an arithmetic evaluation in Standard ML aswell as in the L3 interpreter (evalQ)

gt 1 + 2val it = 3 intgt RuntimeevalQ `0i1 + 2`val it = `0i3` Termterm

Various error messages can occur when using the interpreter for example

gt RuntimeevalQ `1 + 2`Exception- Fail Could not infer all types raised

gt RuntimeevalQ `0i2 div 0`Exception- Except (Div SOME (div (int [`0i2` `0i0`]))) raised

The first error occurs because unannotated number literals are regarded as bit-vector values andhere the vector width cannot be inferred

L3 declarations can be made using the function loadQ The following sequence shows thedeclaration and manipulation of a global variable

gt RuntimeloadQ `declare n nat`ltVARgt nval it = () unit

gt RuntimeevalQ `n`val it = `UNKNOWNnat` Termterm

gt RuntimeevalQ ` n lt- 3 n `val it = `0n3` Termterm

The global state can be examined using the function show for example

gt Runtimeshow()val it = [(n `0n3`)] Evalterm_stack

The state can be ldquowipedrdquo clean using the function reset and all declarations can be wiped usinglsquoresetAllrsquo for example

gt Runtimereset()val it = () unitgt Runtimeshow()val it = [(n `UNKNOWNnat`)] Evalterm_stack

gt RuntimeresetAll()val it = () unitgt Runtimeshow()val it = [] Evalterm_stack

The function lsquoLoadQrsquo is similar to lsquoloadQrsquo but it performs a lsquoresetAllrsquo before making declarations

17

Constants The structure Consts provides various functions for working with L3 constantsMany of the operation in the Consts structure will be of little interest to end-users however itcan be used to display some helpful information

The function ConstslookupConst can be used to lookup an operation for example

gt ConstslookupConst Log2val it = Primitive [(bits(a) -gt bits(a) -) (nat -gt nat -)] const

Since lsquoLog2rsquo is a primitive operation only the valid types (ordered by overload priority) are showWith user operations the internal representation (definition) of the operation will be shownfor example

gt RuntimeLoadQ `unit demo () = ()`gt ConstslookupConst demoval it = Definition (Abs ([(_ (unit -))] unit -gt unit `()`) NONE 1)

Constsconst

The functions ConstslistDefinitions and ConstslistExceptions provide details of all useroperations and exceptions respectively The function lsquoConstsstatsrsquo gives a summary of all thecurrent declarations

gt Constsstats()Primitives 188Destructors 5Constructors 0Accessors 0Exceptions 0User operations 1Instruction definitions 0

Here the constructors for primitive types (such as lsquoConsrsquo) are counted under ldquoprimitivesrdquo

Types The Types structure can be used to display information relating to L3 types In partic-ular this structure provides the functions TypeslookupConst and TypeslistConsts which aredemonstrated below

gt RuntimeloadQ `construct enum One Two Three`gt TypeslistConsts()val it =

[(enumeq = true ast = false def = Constructors (Enum ltdict(3)gt) num = 0)]

(string typeconst) list

gt TypeslookupConst intval it = SOME eq = true ast = false def = BaseType num = ~1

typeconst option

18

Loading and Exporting Specifications When writing an L3 specification it is expected thatuser declarations will be contained in an L3 source file A sample instruction set specification(tinyspec) can be found in the L3 distribution subdirectory examples This specification isbased on Thackerrsquos pedagogical Tiny 3 architecture it can be loaded as follows

gt RuntimeLoadF tinyspecLoading tinyspecltTYPgt regTltTYPgt wordTmiddot middot middotltFUNgt test_progDone

The string argument to the functions RuntimeloadF and RuntimeLoadF can be in the form ofa comma separated list of files which will be loaded in order That is the call

RuntimeloadF aspec bspec

will load aspec followed by bspecThe function HolExportexport will export the current L3 specification in the form of an

HOL4 script for example

gt HolExportexport tinyraiseexception okfunction okmiddot middot middotmextend skipmunextend skipCreated file tinyScriptsmlCreated file tinyLibsmlCreated file tinyLibsigDone

The function HolExportspec provides a convenient shortcut for performing LoadF and exportusing just a single call for example HolExportspec (tinyspec tiny) will perform theload and export presented above

L3 is capable of exporting two styles of HOL specification an explicitly monadic version(based on state_transformerTheory) and a version that directly manipulates state using let-expressions (which is the default style) For example a monadic version of the Tiny specifi-cation can be exported using the command HolExportspec (tinyspec tiny monadic)Other export options include sigdocs nosigdocs (for setting HOLrsquos TheoryPPinclude_docstrace variable) bigrecords nobigrecords (for controlling HOLrsquos Datatypebig_record_size)and underflowbefore nounderflowbefore (for selecting the required IEEE 754 underflow be-haviour)

Generated HOL4 specifications are not designed to be manually edited (or human readable)To build an L3 specification script the HOL library Import is needed This library is currentlylocated in the directory $HOL_DIRexamplesl3-machine-codecommon and so adding this path tothe INCLUDES variable of a local Holmakefile is recommended The examplesl3-machine-codedirectory contains various examples of using L3 generated specifications

19

Testing Specifications Having written an L3 specification it is fairly easy to write code (inStandard ML) that runs test vectors Code for running the tinyspec example can be found inthe file run-tinyspec In this test harness the Tiny state is initialised and a small test programis loaded simply by evaluating the expression lsquoinitialize (test_prog)rsquo

It is also possible to evaluate (run) models that have been exported to HOL4 The filerun-tinysml shows how this can be accomplished for the Tiny example

20

A Primitive Types and OperationsThe primitive types are as follows

unit bool char nat int bits(middot) rounding

There are two infix type constructors lsquorsquo for pairs and lsquo-gtrsquo for maps There are also postfix typeconstructors lsquosetrsquo lsquooptionrsquo and lsquolistrsquo for example sets of strings are represented by the typelsquostring setrsquo The following sections describe these primitive types together with some detailsof associated operations The following constants and operations are available

nullary () Nil None false roundTiesToEven roundTowardNegativeroundTowardPositive roundTowardZero true

prefix - ~ Abs Cardinality Cons Difference Drop Element FP32_AbsFP32_Add FP32_Equal FP32_IsNan FP32_LessThan FP32_MulFP32_Neg FP32_Sub FP64_Abs FP64_Add FP64_Equal FP64_IsNanFP64_LessThan FP64_Mul FP64_Neg FP64_Sub FromBinStringFromDecString FromHexString Fst Head IndexOf InitMapIntersection IsAlpha IsAlphaNum IsDigit IsHexDigit IsLowerIsMember IsSome IsSubset IsUpper Length Log2 Max Min MsbQuotRem Remove RemoveDuplicates RemoveExcept ReverseSetOfList SignExtend SignedMax SignedMin Size Snd Some TailTake ToLower ToUpper Union Update ValOf ZeroExtend not

infix = ampamp + - lt lt+ lt= lt=+ ltgt == gt gt+ gt= gt=+ ^ || gtgtltlt gtgt+ ltlt gtgt and div in insert mod notin or quot rem

sdivsmodother middot ltmiddotgt middot ltmiddotmiddotgt [middot] fields splitl splitr tokens

Many arithmetic operations are overloaded Unless otherwise stated the order of selection islsquobits(middot)rsquo lsquonatrsquo lsquointrsquo and then lsquobool listrsquo

A1 UnitThe type lsquounitrsquo represents the singleton set containing the value lsquo()rsquo The primary use of thistype is as the return type for procedures

A2 BoolThe type lsquoboolrsquo represents the two element set B = lsquotruersquo lsquofalsersquo The following standardBoolean operations are available

negation not bool rarr boolconjunction and booltimes bool rarr booldisjunction or booltimes bool rarr boolequality == αtimesα rarr boolnon-equality ltgt = αtimesα rarr bool

21

The infix operators lsquoandrsquo and lsquoorrsquo are interpreted with short-circuit evaluation for example in theexpression lsquofalse and f()rsquo the value of lsquof()rsquo is not computed as the overall expression will alwaysevaluate to false This short-circuiting influences the side-effects that occur during expressionevaluation

There are two prefix symbols for logical negation (these are semantically identical) with lsquorsquobinding slightly tighter than lsquonotrsquo This distinction is becomes significant when working withequalities for example lsquonot a == brsquo is taken to be not(a = b) whereas lsquoa == brsquo is (nota) = b

Equality is only defined with respect to equality types represented here by the type variableα An equality type is any type built without the used of the map operator lsquo-gtrsquo

A3 NatThe type lsquonatrsquo represents the natural numbers N = 0 1 2 The following operations areavailable

logarithm (base two) Log2 nat rarr natminimum value Min nattimes nat rarr natmaximium value Max nattimes nat rarr natless than lt nattimes nat rarr boolgreater than gt nattimes nat rarr boolless than or equal to lt= nattimes nat rarr boolgreater than or equal to gt= nattimes nat rarr booladdition + nattimes nat rarr natsubtraction - nattimes nat rarr natmultiplication nattimes nat rarr natexponentiation nattimes nat rarr natdivision div nattimes nat rarr natmodulus mod nattimes nat rarr nat

The lsquodivrsquo and lsquomodrsquo operations satisfy the following property

foralln 0 lt n =rArr forallk k = (k div n) lowast n+ (k mod n) and (k mod n) lt n

The expressions lsquoLog2(0)rsquo lsquox div 0rsquo and lsquox mod 0rsquo are all undefined 17

A4 IntThe type lsquointrsquo represents the integers Z = Ncupminus1minus2minus3 The following operations areavailable

17The interpreter will raise an exception when attempting to evaluate them

22

unary minus - int rarr intabsolute value Abs int rarr intminimum value Min inttimes int rarr intmaximum value Max inttimes int rarr intless than lt inttimes int rarr boolgreater than gt inttimes int rarr boolless than or equal to lt= inttimes int rarr boolgreater than or equal to gt= inttimes int rarr booladdition + inttimes int rarr intsubtraction - inttimes int rarr intmultiplication inttimes int rarr intexponentiation inttimes nat rarr intquotient and remainder QuotRem inttimes int rarr inttimes intquotient quot inttimes int rarr intremainder rem inttimes int rarr intdivision div inttimes int rarr intmodulus mod inttimes int rarr int

The operation lsquoAbsrsquo gives an positive integer value for example lsquoAbs(-2)rsquo = lsquo2rsquo The integeroperations lsquoquotrsquo and lsquodivrsquo are related to natural number division as follows

i quot j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

and

i div j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(minusi) div n(j))minus 1 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i and n(i) mod n(minusj) = 0

minus z(n(i) div n(minusj))minus 1 j lt 0 and 0 le i and n(i) mod n(minusj) = 0

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

where z NrarrZ and n ZrarrN are value preserving maps The lsquoremrsquo and lsquomodrsquo operations satisfythe equations

i rem j =

iminus (i quot j) lowast j j = 0

undefined j = 0i mod j =

iminus (i div j) lowast j j = 0

undefined j = 0

A5 Bit-vectorsThe type lsquobits(n)rsquo represents fixed-width (n-bit) words also known as bit-vectors for examplebits(32) is the type of 32-bit machine words18 The bits type can be viewed as representing

18These are called double-words (dword) in the x86 architecture and simply words in the ARM architecture

23

the set Zn = 0 1 2nminus1 for some 0 lt n At the type system level no distinction is madebetween signed and unsigned words however some operations (such as orderings) have signedand unsigned variants

The following bit-vector operations are available

1rsquos complement ~ bits(n) rarr bits(n)2rsquos complement - bits(n) rarr bits(n)absolute value Abs bits(n) rarr bits(n)logarithm (base two) Log2 bits(n) rarr bits(n)zero-extend ZeroExtend bits(m) rarr bits(n)sign-extend SignExtend bits(m) rarr bits(n)reverse bits Reverse bits(n) rarr bits(n)minimum value (u) Min bits(n)times bits(n) rarr bits(n)maximum value (u) Max bits(n)times bits(n) rarr bits(n)minimum value (s) SignedMin bits(n)times bits(n) rarr bits(n)maximum value (s) SignedMax bits(n)times bits(n) rarr bits(n)widthsize Size bits(n) rarr natmost-significant (sign) bit Msb bits(n) rarr boolbit value middot ltmiddotgt bits(n)times nat rarr boolbit field middot ltmiddotmiddotgt bits(m)times nattimes nat rarr bits(n)concatenation bits(m)times bits(n) rarr bits(p)duplication ^ bits(m)times nat rarr bits(n)less than (s) lt bits(n)times bits(n) rarr boolgreater than (s) gt bits(n)times bits(n) rarr boolless than or equal to (s) lt= bits(n)times bits(n) rarr boolgreater than or equal to (s) gt= bits(n)times bits(n) rarr boolless than (u) lt+ bits(n)times bits(n) rarr boolgreater than (u) gt+ bits(n)times bits(n) rarr boolless than or equal to (u) lt=+ bits(n)times bits(n) rarr boolgreater than or equal to (u) gt=+ bits(n)times bits(n) rarr booladdition + bits(n)times bits(n) rarr bits(n)subtraction - bits(n)times bits(n) rarr bits(n)multiplication bits(n)times bits(n) rarr bits(n)quotient (s) quot bits(n)times bits(n) rarr bits(n)remained (s) rem bits(n)times bits(n) rarr bits(n)division (u) div bits(n)times bits(n) rarr bits(n)modulus (u) mod bits(n)times bits(n) rarr bits(n)division (s) sdiv bits(n)times bits(n) rarr bits(n)modulus (s) smod bits(n)times bits(n) rarr bits(n)bitwise conjunction ampamp bits(n)times bits(n) rarr bits(n)bitwise disjunction || bits(n)times bits(n) rarr bits(n)bitwise exclusive-or bits(n)times bits(n) rarr bits(n)

Unsigned operations are labelled with (u) and signed operations are labelled with (s)The shift operations support shifting by either a bit-vector value or by a natural number value

The overloading is resolved such that the lsquonatrsquo variant is selected over the lsquobits(middot)rsquo version Theshift operations are

24

left-shift ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (u) gtgt+ bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (s) gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate left ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate right gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

A number of operations are undefined depending on the types of their domain and rangeThis is detailed in the following table

Operation Undefined when

ZeroExtend(x`n)`m m lt nSignExtend(x`n)`m m lt n(x`m)ltpgt m le p(x`m)lthlgt`n n = h+ 1minus l or h lt l orm le h((xm) (yn))`p p = m+ n((x`m) ^ n)`p p = m middot n (which covers n = 0)

The type checker will fail when these conditions are obviously violated Alternatively the inter-preter may raise a runtime error when these conditions are not met

As before the expressions lsquoLog2(0)rsquo lsquox quot 0rsquo lsquox rem 0rsquo lsquox div 0rsquo and lsquox mod 0rsquo are allundefined

A6 Bit-stringsVarious bit-string operation are defined over the type lsquobool listrsquo These are listed below

bit value middot ltmiddotgt bool listtimes nat rarr boolbit field middot ltmiddotmiddotgt bool listtimes nattimes nat rarr bool listconcatenation bool listtimes bool list rarr bool listduplication ^ bool listtimes nat rarr bool listaddition + bool listtimes bool list rarr bool listbitwise conjunction ampamp bool listtimes bool list rarr bool listbitwise disjunction || bool listtimes bool list rarr bool listbitwise exclusive-or bool listtimes bool list rarr bool listleft-shift ltlt bool listtimes nat rarr bool listright-shift gtgt+ bool listtimes nat rarr bool listrotate-right gtgt bool listtimes nat rarr bool list

The bit value operation gives the truth value of a bit-string at a given bit position for example

lsquo0s1101lt0gtrsquo = lsquotruersquo lsquo0s1101lt1gtrsquo = lsquofalsersquo lsquo0s1101lt2gtrsquo = lsquotruersquolsquo0s1101lt3gtrsquo = lsquotruersquo lsquo0s1101lt4gtrsquo = lsquofalsersquo lsquo0s1101lt5gtrsquo = lsquofalsersquo

25

The least-significant bit (position zero) occurs to the right of the bit-string The bit value oper-ation gives lsquofalsersquo when the bit position is greater than the size of the bit-string

The bit field operation extracts a range of bits from a bit-string For example

lsquo0s1101lt31gtrsquo = lsquo0s110rsquo and lsquo0s1101lt52gtrsquo = lsquo0s0011rsquo

In the bit-string expression xlthlgt the size of the result is always h + 1 minus l and the result isundefined when h lt l

Bit-string addition does not require the arguments to be of the same size and it gives anon-truncated result For example

lsquo0s101 + 0s1rsquo = lsquo0s110rsquo and lsquo0s101 + 0s11rsquo = lsquo0s1000rsquo

The operation ltlt performs a left-shift for example lsquo0s1101 ltlt 2rsquo = lsquo0s110100rsquo The oper-ation lsquorsquo is bit-string concatenation and lsquo^rsquo is duplication for example

lsquo0s101 0s11rsquo = lsquo0s10111rsquo and lsquo0s101 ^ 3rsquo = lsquo0s101101101rsquo

Regular list operations work as one would expect over bit-strings for example lsquoHead (0s101)rsquois a valid expression with value lsquotruersquo

A7 Characters and StringsThe following built-in functions are available for characters and strings

is alphabetic IsAlpha char rarr boolis alpha-numeric IsAlphaNum char rarr boolis decimal digit IsDigit char rarr boolis hexadecimal digit IsHexDigit char rarr boolis lowercase IsLower char rarr boolis uppercase IsUpper char rarr boolparse binary FromBinString string rarr num optionparse decimal FromDecString string rarr num optionparse hexadecimal FromHexString string rarr num optionconvert to lowercase ToLower string rarr stringconvert to uppercase ToUpper string rarr string

The following string operations are useful for parsing

split from the left splitl (char rarr bool) times string rarr string times stringsplit from the right splitr (char rarr bool) times string rarr string times stringsplit into fields fields (char rarr bool) times string rarr string listsplit into tokens tokens (char rarr bool) times string rarr string list

These are based on the SML functions Substringsplitl Substringsplitr Stringfieldsand Stringtokens Character predicates are declared using special syntax for example theexpression

splitl space or hexdigit and not in set a f ( 12bcab)

gives the result lsquo( 12bc ab)rsquo

26

A8 Floating-pointThe L3 language does not provide specialised types for representing floating-point numbersHowever 32-bit (single precision) and 64-bit (double precision) bit-vector values can be treatedas floating-point numbers the following IEEE compliant encoding formats are assumed

31 30 23 22 0

s e m1 8 23

63 62 52 51 0

s e m1 11 52

Here lsquosrsquo is the sign bit (set to lsquo1rsquo for negative numbers) lsquoersquo is a biased exponent value and lsquomrsquo is thesignificand The following constants and operations are available (where lsquofprsquo stands for bits(32)or bits(64) depending on the name of the operation)

rounding modes roundTiesToEvenroundTowardPositiveroundTowardNegativeroundTowardZero

ieee_rounding

flags (record) DivideByZero InvalidOpOverflow PrecisionUnderflow

ieee_flagsrarrbool

comparison values FP_LT FP_EQ FP_GT FP_UN ieee_compare

convert format FP32_ToFP64 fp32rarrfp64convert format FP64_ToFP32 ieee_roundingtimes fp64rarrfp32convert format FP64_ToFP32_ ieee_roundingtimes fp64rarr

ieee_flagstimes fp32from integer FP32|64_FromInt ieee_roundingtimes intrarrfpto integer FP32|64_ToInt ieee_roundingtimes fprarrint optionfrom string FP32|64 stringrarrfp

negative zero FP32|64_NegZero fppositive zero FP32|64_PosZero fpnegative infinity FP32|64_NegInf fppositive infinity FP32|64_PosInf fpa quiet NaN FP32|64_qNan fpa signalling NaN FP32|64_sNan fp

is integral FP32|64_IsIntegral fprarrboolis finite FP32|64_IsFinite fprarrboolis NaN FP32|64_IsNan fprarrboolis signalling NaN FP32|64_IsSignallingNan fprarrboolis normal FP32|64_IsNormal fprarrboolis sub-normal FP32|64_IsSubnormal fprarrboolis zero FP32|64_IsZero fprarrbool

27

comparison FP32|64_Compare fptimes fprarrieee_compareequality FP32|64_Equal fptimes fprarrboolless than FP32|64_LessThan fptimes fprarrboolless than or equal FP32|64_LessEqual fptimes fprarrboolgreater than FP32|64_GreaterThan fptimes fprarrboolgreater than or equal FP32|64_GreaterEqual fptimes fprarrbool

absolute FP32|64_Abs fprarrfpnegation FP32|64_Neg fprarrfpsquare root FP32|64_Sqrt ieee_roundingtimes fprarrfp(with flags) FP32|64_Sqrt_ ieee_roundingtimes fprarrieee_flagstimes fpaddition FP32|64_Add ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Add_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpsubtraction FP32|64_Sub ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Sub_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpmultiplication FP32|64_Mul ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Mul_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpfused multiply-add FP32|64_MulAdd ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulAdd_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpfused multiply-sub FP32|64_MulSub ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulSub_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpdivision FP32|64_Div ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Div_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fp

The L3 interpreter supports evaluation for 32-bit and 64-bit floating-point expressions but onlywhen running on an x86 machine that supports SSE2 extensions (Pentium 4 and later) Thefused multiply-addsub operations can only be interpreted on machines supporting the FMAextension which came in with the 4th generation (Haswell) Intel processors These restrictionsalso apply to any Standard ML code that is generated by L3

The IEEE 754 standard permits a number of different ways to flag underflow L3 predomi-nantly supports the x86 interpretation which detects underflow after rounding However whenexporting to HOL4 it is possible to choose detection before rounding which for example issuited to ARM instruction set models

A9 Miscellaneous operationsThe following operations are available

pair constructor αtimes β rarr αtimes βfirst of pair Fst αtimes β rarr αsecond of pair Snd αtimes β rarr β

casting [middot] α rarr βinitialise a map InitMap α rarr (βrarrα)

28

option constructor Some αrarrα optionoption projection ValOf α option rarr αoption test IsSome α option rarr bool

set membership in αtimesα set rarr boolset non-membership notin αtimesα set rarr boolset insertion insert αtimesα set rarrα setset union Union α settimesα set rarrα setset intersection Intersect α settimesα set rarrα setset difference Difference α settimesα set rarrα setset subset test IsSubset α settimesα set rarr boolset cardinality Cardinality α setrarr natset from a list SetOfList α list rarrα set

empty list Nil α listlist constructor Cons αtimesα list rarr α listlist head Head α list rarr αlist tail Tail α list rarr α listlist length Length α list rarr natlist concatenation α listtimesα list rarr α listlist flatten Concat α list list rarr α listlist element Element nattimesα list rarr αlist prefix Take nattimesα list rarr α listlist drop prefix Drop nattimesα list rarr α listlist pad left PadLeft αtimes nattimesα list rarr α listlist pad right PadRight αtimes nattimesα list rarr α listlist update Update αtimes nattimesα list rarr α listlist difference Remove α listtimesα list rarr α listlist intersection RemoveExcept α listtimesα list rarr α listlist without duplicates RemoveDuplicates α listrarr α listlist membership IsMember αtimesα list rarr boollist member position IndexOf αtimesα list rarr nat option

Sets are only defined over equality types see Appendix A2 The casting map is defined overcast-able types (as represented by the polymorphic type variables α and β) these are the primitivetypes (with the exception of lsquounitrsquo) and user defined enumerated types Assume lsquoEnumrsquo and lsquoEnum2rsquoare declared with

construct Enum One Two Three construct Enum2 Four Five Six Seven

The cast operations are described in Tables 1 to 7

29

Table 1 Cast to lsquoboolrsquo

From Operation Examples

bool identity lsquo[true]boolrsquo = lsquotruersquostring parse bool lsquo[true]boolrsquo = lsquotruersquo

lsquo[false]boolrsquo = lsquofalsersquootherwise undefined

nat is not zero lsquo[0n3]boolrsquo = lsquotruersquolsquo[0n0]boolrsquo = lsquofalsersquo

int is not zero lsquo[-0i1]boolrsquo = lsquotruersquolsquo[0i0]boolrsquo = lsquofalsersquo

bool list is not zero lsquo[0s11]boolrsquo = lsquotruersquolsquo[0s0]boolrsquo = lsquofalsersquo

bits(middot) is not zero lsquo[3`3]boolrsquo = lsquotruersquolsquo[0`3]boolrsquo = lsquofalsersquo

Enum is not the first element lsquo[One]boolrsquo = lsquofalsersquolsquo[Two]boolrsquo = lsquotruersquo

Table 2 Cast to lsquostringrsquo

From Operation Examples

bool name lsquo[true]stringrsquo = lsquotruersquostring identity lsquo[hello]stringrsquo = lsquohellorsquonat decimal lsquo[0n3]stringrsquo = lsquo3rsquoint signed decimal lsquo[-0i1]stringrsquo = lsquo~1rsquobool list binary lsquo[0s11]stringrsquo = lsquo11rsquobits(middot) unsigned hexadecimal lsquo[139`8]stringrsquo = lsquo8BrsquoEnum name lsquo[One]stringrsquo = lsquoOnersquo

30

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

operation is total (terminates on all inputs) If an L3 function is non-terminating then it willbe impossible to export that definition to HOL4 If a function is terminating but the standardautomation of HOL4 is unable to construct a termination proof then it may be necessary toprovide the prover with a hint in the form of a measure

Consider the following specification

declare m bits(8) -gt bits(8)

unit load (abits(8) lbits(8) list) =match l

case Nil =gt nothingcase Cons (h t) =gt m(a) lt- h load (a + 1 t)

The lsquoloadrsquo operation recurses over the list lsquolrsquo loading values into the map lsquomrsquo At the time ofwriting this documentation trying to build the exported HOL4 version of this specificationgives rise to the following error message

Initial goal

existRWF R andforallstate a l h t

(l = ht) rArrR ((a + 1wt)state with m = (a =+ h) statem) ((al)state)

Exception raised at TotalDefnDefinebetween beginning of frag 0 and end of frag 0at TotalDefndefnDefine

Unable to prove termination

Try using TotalDefntDefine ltnamegt ltquotationgt lttacgt

This occurs because HOL4 is unable to automatically prove that lsquoloadrsquo always terminates Toget around this problem the original L3 specification can be modified to contain an annotationas follows

unit load (abits(8) lbits(8) list) measure Length(l) =

The metadata lsquomeasure Length(l)rsquo tells HOL4 to examine the length of the list lsquolrsquo since thisvalue will decrease upon each recursive call to lsquoloadrsquo When the length of the list is zero (thelsquoNilrsquo case) there are no recursive calls so termination is guaranteed

The expression occurring after the lsquomeasurersquo keyword must be of type lsquonatrsquo After provid-ing a measure it is still possible that HOL4 will fail to prove termination either because thesupplied measure is incorrect or because the termination proof is non-trivial (requires humanguidance andor custom lemmas) If this occurs then users should either simplifyrewrite theirspecifications or if necessary report the problem

13

115 Instruction Set DefinitionsWhen working with instruction set models it is helpful to construct a datatype that representsthe set of machine (low-level) instructions This datatype constitutes a simple form of abstractsyntax tree (AST) and it can be used to build instruction decoders (identifying machine-codeinstructions and splitting opcodes into sub-fields) instruction encoders (generating opcodes fora given instruction) next-state functions (applying a semantics function for a given instruction)and assembly code parsers

By way of an example consider the MIPS instruction ANDI this instruction has the assemblycode syntax

ANDI rt rs immediate

and the following 32-bit machine-code encoding

31 26 25 21 20 16 15 0

001100 rs rt immediate6 5 5 16

The semantics of this instruction can be expressed with the operation

unit run_ANDI (rsbits(5) rtbits(5) immbits(16)) =GPR(rt) lt- GPR(rs) ampamp ZeroExtend (imm)

One could use this operation to directly specify a next-state function which would be of theform

unit Next =match Fetch -- fetches a 32-bit opcode from memory

middot middot middotcase 001100 rs rt imm =gt run_ANDI (rs rt imm)middot middot middot

This style of specification is direct and concise however it does lack some of the flexibility thatcomes with using an instruction datatype The L3 language provides support for an slightlydifferent style of specification This alternative approach is explained by first examining howone would specify things manually (explicitly) and then showing how L3 can streamline thisprocess

Firstly one could explicitly define an AST datatype for MIPS instructions it would be ofthe form

construct instruction

middot middot middotANDI bits(5) bits(5) bits(16)middot middot middot

14

This datatype provides a suitable constructor for the ANDI instruction It is now possible to definea decoder which maps opcodes onto AST entries for example

instruction Decode (opcbits(32)) =match opc

middot middot middotcase 001100 rs rt imm =gt ANDI (rs rt imm)middot middot middot

This decoder can be used to define our next-state function that is

unit Next = Run (Decode (Fetch))

where lsquoRunrsquo is defined by

unit Run (iinstruction) =match i

middot middot middotcase ANDI (args) =gt run_ANDI (args)middot middot middot

When working with full-scale architecture specifications (where the AST type is large) thereare some clear overheads associated with implementing this approach (in comparison with theAST free version) It becomes challenging to maintain the AST datatype declaration and tokeep it correctly synchronised with the instruction semantics operations (such as lsquorun_ANDIrsquo)and the definition of lsquoRunrsquo Note however that there is great uniformity in the AST datatypedeclaration and also in the definition of lsquoRunrsquo As such L3 is able to automatically define bothof these for the user

To make use of this automation the declaration of lsquorun_ANDIrsquo is simply modified to

define ANDI (rsbits(5) rtbits(5) immbits(16)) =GPR(rt) lt- GPR(rs) ampamp ZeroExtend (imm)

The lsquodefinersquo keyword tells L3 to define a semantics function14 (as before) and to also create anew lsquoinstructionrsquo datatype AST entry furthermore the two will be linked with the automaticconstruction of a lsquoRunrsquo function The lsquoinstructionrsquo type and lsquoRunrsquo function become defined (inscope) following the declaration lsquodefine Runrsquo After this declaration it is no longer possible touse the lsquodefinersquo construct again however it does become possible to define functions such aslsquoDecodersquo and lsquoNextrsquo

Specifications that are based on using lsquodefinersquo gain the benefits of declaring an instructionAST datatype without the downside of laborious coding overheads In the example above theoverhead amounts to one extra line of code this comes from defining a next-state function thatcalls the dedicated decode function followed by a call to lsquoRunrsquo

One of the key advantages of declaring an instruction datatype is that it makes it consider-ably easier to develop tools that work with assembly code syntax (performing parsing encoding

14This function is internally called lsquodfnANDIrsquo instead of lsquorun_ANDIrsquo

15

and pretty-printing) In this case it is relatively easy for example to map between the MIPSinstruction syntax andi $5 $6 1024 and the expression lsquoANDI (5 6 1024)rsquo Defining anencoder in L3 is relatively straightforward for example

bits(32) Encode (iinstruction) =match i

middot middot middotcase ANDI (rs rt imm) =gt 001100 rs rt immmiddot middot middot

Such a function can be used to write a MIPS assembler which would map the assembly codesyntax andi $5 $6 1024 onto the machine-code value 0x30c50400

2 TutorialThis section gives a brief overview of how to install and use L3

Installation The sources for L3 can be downloaded from the following webpage

wwwclcamacuk~acjf3l3

The file l3tarbz2 can be unpacked with the command

$ tar xvjf l3tarbz2

This will create a directory of the form L3-YYYY-MM-DD where the year month and day willcorrespond with the release date The current version of L3 depends upon PolyML 57 whichcan be obtained from the site polymlorg If PolyML is installed then L3 can be built as follows

$ cd L3-YYYY-MM-DD$ make

Once built the following should appear when you start L315

$ l3ltlt L3 gtgtgt

Users should consider running L3 with the command rlwrap l316

15This assumes that the directory L3-YYYY-MM-DDbin has been added to the PATH environment variable16Details on rlwrap utility can be found at the site freecodecomprojectsrlwrap

16

Basic Interaction The command prompt for L3 is essentially the read-eval-print loop (REPL)of PolyML As such users are free to write arbitrary Standard ML code The structure Runtimeenables interaction with L3 The following shows an arithmetic evaluation in Standard ML aswell as in the L3 interpreter (evalQ)

gt 1 + 2val it = 3 intgt RuntimeevalQ `0i1 + 2`val it = `0i3` Termterm

Various error messages can occur when using the interpreter for example

gt RuntimeevalQ `1 + 2`Exception- Fail Could not infer all types raised

gt RuntimeevalQ `0i2 div 0`Exception- Except (Div SOME (div (int [`0i2` `0i0`]))) raised

The first error occurs because unannotated number literals are regarded as bit-vector values andhere the vector width cannot be inferred

L3 declarations can be made using the function loadQ The following sequence shows thedeclaration and manipulation of a global variable

gt RuntimeloadQ `declare n nat`ltVARgt nval it = () unit

gt RuntimeevalQ `n`val it = `UNKNOWNnat` Termterm

gt RuntimeevalQ ` n lt- 3 n `val it = `0n3` Termterm

The global state can be examined using the function show for example

gt Runtimeshow()val it = [(n `0n3`)] Evalterm_stack

The state can be ldquowipedrdquo clean using the function reset and all declarations can be wiped usinglsquoresetAllrsquo for example

gt Runtimereset()val it = () unitgt Runtimeshow()val it = [(n `UNKNOWNnat`)] Evalterm_stack

gt RuntimeresetAll()val it = () unitgt Runtimeshow()val it = [] Evalterm_stack

The function lsquoLoadQrsquo is similar to lsquoloadQrsquo but it performs a lsquoresetAllrsquo before making declarations

17

Constants The structure Consts provides various functions for working with L3 constantsMany of the operation in the Consts structure will be of little interest to end-users however itcan be used to display some helpful information

The function ConstslookupConst can be used to lookup an operation for example

gt ConstslookupConst Log2val it = Primitive [(bits(a) -gt bits(a) -) (nat -gt nat -)] const

Since lsquoLog2rsquo is a primitive operation only the valid types (ordered by overload priority) are showWith user operations the internal representation (definition) of the operation will be shownfor example

gt RuntimeLoadQ `unit demo () = ()`gt ConstslookupConst demoval it = Definition (Abs ([(_ (unit -))] unit -gt unit `()`) NONE 1)

Constsconst

The functions ConstslistDefinitions and ConstslistExceptions provide details of all useroperations and exceptions respectively The function lsquoConstsstatsrsquo gives a summary of all thecurrent declarations

gt Constsstats()Primitives 188Destructors 5Constructors 0Accessors 0Exceptions 0User operations 1Instruction definitions 0

Here the constructors for primitive types (such as lsquoConsrsquo) are counted under ldquoprimitivesrdquo

Types The Types structure can be used to display information relating to L3 types In partic-ular this structure provides the functions TypeslookupConst and TypeslistConsts which aredemonstrated below

gt RuntimeloadQ `construct enum One Two Three`gt TypeslistConsts()val it =

[(enumeq = true ast = false def = Constructors (Enum ltdict(3)gt) num = 0)]

(string typeconst) list

gt TypeslookupConst intval it = SOME eq = true ast = false def = BaseType num = ~1

typeconst option

18

Loading and Exporting Specifications When writing an L3 specification it is expected thatuser declarations will be contained in an L3 source file A sample instruction set specification(tinyspec) can be found in the L3 distribution subdirectory examples This specification isbased on Thackerrsquos pedagogical Tiny 3 architecture it can be loaded as follows

gt RuntimeLoadF tinyspecLoading tinyspecltTYPgt regTltTYPgt wordTmiddot middot middotltFUNgt test_progDone

The string argument to the functions RuntimeloadF and RuntimeLoadF can be in the form ofa comma separated list of files which will be loaded in order That is the call

RuntimeloadF aspec bspec

will load aspec followed by bspecThe function HolExportexport will export the current L3 specification in the form of an

HOL4 script for example

gt HolExportexport tinyraiseexception okfunction okmiddot middot middotmextend skipmunextend skipCreated file tinyScriptsmlCreated file tinyLibsmlCreated file tinyLibsigDone

The function HolExportspec provides a convenient shortcut for performing LoadF and exportusing just a single call for example HolExportspec (tinyspec tiny) will perform theload and export presented above

L3 is capable of exporting two styles of HOL specification an explicitly monadic version(based on state_transformerTheory) and a version that directly manipulates state using let-expressions (which is the default style) For example a monadic version of the Tiny specifi-cation can be exported using the command HolExportspec (tinyspec tiny monadic)Other export options include sigdocs nosigdocs (for setting HOLrsquos TheoryPPinclude_docstrace variable) bigrecords nobigrecords (for controlling HOLrsquos Datatypebig_record_size)and underflowbefore nounderflowbefore (for selecting the required IEEE 754 underflow be-haviour)

Generated HOL4 specifications are not designed to be manually edited (or human readable)To build an L3 specification script the HOL library Import is needed This library is currentlylocated in the directory $HOL_DIRexamplesl3-machine-codecommon and so adding this path tothe INCLUDES variable of a local Holmakefile is recommended The examplesl3-machine-codedirectory contains various examples of using L3 generated specifications

19

Testing Specifications Having written an L3 specification it is fairly easy to write code (inStandard ML) that runs test vectors Code for running the tinyspec example can be found inthe file run-tinyspec In this test harness the Tiny state is initialised and a small test programis loaded simply by evaluating the expression lsquoinitialize (test_prog)rsquo

It is also possible to evaluate (run) models that have been exported to HOL4 The filerun-tinysml shows how this can be accomplished for the Tiny example

20

A Primitive Types and OperationsThe primitive types are as follows

unit bool char nat int bits(middot) rounding

There are two infix type constructors lsquorsquo for pairs and lsquo-gtrsquo for maps There are also postfix typeconstructors lsquosetrsquo lsquooptionrsquo and lsquolistrsquo for example sets of strings are represented by the typelsquostring setrsquo The following sections describe these primitive types together with some detailsof associated operations The following constants and operations are available

nullary () Nil None false roundTiesToEven roundTowardNegativeroundTowardPositive roundTowardZero true

prefix - ~ Abs Cardinality Cons Difference Drop Element FP32_AbsFP32_Add FP32_Equal FP32_IsNan FP32_LessThan FP32_MulFP32_Neg FP32_Sub FP64_Abs FP64_Add FP64_Equal FP64_IsNanFP64_LessThan FP64_Mul FP64_Neg FP64_Sub FromBinStringFromDecString FromHexString Fst Head IndexOf InitMapIntersection IsAlpha IsAlphaNum IsDigit IsHexDigit IsLowerIsMember IsSome IsSubset IsUpper Length Log2 Max Min MsbQuotRem Remove RemoveDuplicates RemoveExcept ReverseSetOfList SignExtend SignedMax SignedMin Size Snd Some TailTake ToLower ToUpper Union Update ValOf ZeroExtend not

infix = ampamp + - lt lt+ lt= lt=+ ltgt == gt gt+ gt= gt=+ ^ || gtgtltlt gtgt+ ltlt gtgt and div in insert mod notin or quot rem

sdivsmodother middot ltmiddotgt middot ltmiddotmiddotgt [middot] fields splitl splitr tokens

Many arithmetic operations are overloaded Unless otherwise stated the order of selection islsquobits(middot)rsquo lsquonatrsquo lsquointrsquo and then lsquobool listrsquo

A1 UnitThe type lsquounitrsquo represents the singleton set containing the value lsquo()rsquo The primary use of thistype is as the return type for procedures

A2 BoolThe type lsquoboolrsquo represents the two element set B = lsquotruersquo lsquofalsersquo The following standardBoolean operations are available

negation not bool rarr boolconjunction and booltimes bool rarr booldisjunction or booltimes bool rarr boolequality == αtimesα rarr boolnon-equality ltgt = αtimesα rarr bool

21

The infix operators lsquoandrsquo and lsquoorrsquo are interpreted with short-circuit evaluation for example in theexpression lsquofalse and f()rsquo the value of lsquof()rsquo is not computed as the overall expression will alwaysevaluate to false This short-circuiting influences the side-effects that occur during expressionevaluation

There are two prefix symbols for logical negation (these are semantically identical) with lsquorsquobinding slightly tighter than lsquonotrsquo This distinction is becomes significant when working withequalities for example lsquonot a == brsquo is taken to be not(a = b) whereas lsquoa == brsquo is (nota) = b

Equality is only defined with respect to equality types represented here by the type variableα An equality type is any type built without the used of the map operator lsquo-gtrsquo

A3 NatThe type lsquonatrsquo represents the natural numbers N = 0 1 2 The following operations areavailable

logarithm (base two) Log2 nat rarr natminimum value Min nattimes nat rarr natmaximium value Max nattimes nat rarr natless than lt nattimes nat rarr boolgreater than gt nattimes nat rarr boolless than or equal to lt= nattimes nat rarr boolgreater than or equal to gt= nattimes nat rarr booladdition + nattimes nat rarr natsubtraction - nattimes nat rarr natmultiplication nattimes nat rarr natexponentiation nattimes nat rarr natdivision div nattimes nat rarr natmodulus mod nattimes nat rarr nat

The lsquodivrsquo and lsquomodrsquo operations satisfy the following property

foralln 0 lt n =rArr forallk k = (k div n) lowast n+ (k mod n) and (k mod n) lt n

The expressions lsquoLog2(0)rsquo lsquox div 0rsquo and lsquox mod 0rsquo are all undefined 17

A4 IntThe type lsquointrsquo represents the integers Z = Ncupminus1minus2minus3 The following operations areavailable

17The interpreter will raise an exception when attempting to evaluate them

22

unary minus - int rarr intabsolute value Abs int rarr intminimum value Min inttimes int rarr intmaximum value Max inttimes int rarr intless than lt inttimes int rarr boolgreater than gt inttimes int rarr boolless than or equal to lt= inttimes int rarr boolgreater than or equal to gt= inttimes int rarr booladdition + inttimes int rarr intsubtraction - inttimes int rarr intmultiplication inttimes int rarr intexponentiation inttimes nat rarr intquotient and remainder QuotRem inttimes int rarr inttimes intquotient quot inttimes int rarr intremainder rem inttimes int rarr intdivision div inttimes int rarr intmodulus mod inttimes int rarr int

The operation lsquoAbsrsquo gives an positive integer value for example lsquoAbs(-2)rsquo = lsquo2rsquo The integeroperations lsquoquotrsquo and lsquodivrsquo are related to natural number division as follows

i quot j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

and

i div j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(minusi) div n(j))minus 1 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i and n(i) mod n(minusj) = 0

minus z(n(i) div n(minusj))minus 1 j lt 0 and 0 le i and n(i) mod n(minusj) = 0

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

where z NrarrZ and n ZrarrN are value preserving maps The lsquoremrsquo and lsquomodrsquo operations satisfythe equations

i rem j =

iminus (i quot j) lowast j j = 0

undefined j = 0i mod j =

iminus (i div j) lowast j j = 0

undefined j = 0

A5 Bit-vectorsThe type lsquobits(n)rsquo represents fixed-width (n-bit) words also known as bit-vectors for examplebits(32) is the type of 32-bit machine words18 The bits type can be viewed as representing

18These are called double-words (dword) in the x86 architecture and simply words in the ARM architecture

23

the set Zn = 0 1 2nminus1 for some 0 lt n At the type system level no distinction is madebetween signed and unsigned words however some operations (such as orderings) have signedand unsigned variants

The following bit-vector operations are available

1rsquos complement ~ bits(n) rarr bits(n)2rsquos complement - bits(n) rarr bits(n)absolute value Abs bits(n) rarr bits(n)logarithm (base two) Log2 bits(n) rarr bits(n)zero-extend ZeroExtend bits(m) rarr bits(n)sign-extend SignExtend bits(m) rarr bits(n)reverse bits Reverse bits(n) rarr bits(n)minimum value (u) Min bits(n)times bits(n) rarr bits(n)maximum value (u) Max bits(n)times bits(n) rarr bits(n)minimum value (s) SignedMin bits(n)times bits(n) rarr bits(n)maximum value (s) SignedMax bits(n)times bits(n) rarr bits(n)widthsize Size bits(n) rarr natmost-significant (sign) bit Msb bits(n) rarr boolbit value middot ltmiddotgt bits(n)times nat rarr boolbit field middot ltmiddotmiddotgt bits(m)times nattimes nat rarr bits(n)concatenation bits(m)times bits(n) rarr bits(p)duplication ^ bits(m)times nat rarr bits(n)less than (s) lt bits(n)times bits(n) rarr boolgreater than (s) gt bits(n)times bits(n) rarr boolless than or equal to (s) lt= bits(n)times bits(n) rarr boolgreater than or equal to (s) gt= bits(n)times bits(n) rarr boolless than (u) lt+ bits(n)times bits(n) rarr boolgreater than (u) gt+ bits(n)times bits(n) rarr boolless than or equal to (u) lt=+ bits(n)times bits(n) rarr boolgreater than or equal to (u) gt=+ bits(n)times bits(n) rarr booladdition + bits(n)times bits(n) rarr bits(n)subtraction - bits(n)times bits(n) rarr bits(n)multiplication bits(n)times bits(n) rarr bits(n)quotient (s) quot bits(n)times bits(n) rarr bits(n)remained (s) rem bits(n)times bits(n) rarr bits(n)division (u) div bits(n)times bits(n) rarr bits(n)modulus (u) mod bits(n)times bits(n) rarr bits(n)division (s) sdiv bits(n)times bits(n) rarr bits(n)modulus (s) smod bits(n)times bits(n) rarr bits(n)bitwise conjunction ampamp bits(n)times bits(n) rarr bits(n)bitwise disjunction || bits(n)times bits(n) rarr bits(n)bitwise exclusive-or bits(n)times bits(n) rarr bits(n)

Unsigned operations are labelled with (u) and signed operations are labelled with (s)The shift operations support shifting by either a bit-vector value or by a natural number value

The overloading is resolved such that the lsquonatrsquo variant is selected over the lsquobits(middot)rsquo version Theshift operations are

24

left-shift ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (u) gtgt+ bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (s) gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate left ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate right gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

A number of operations are undefined depending on the types of their domain and rangeThis is detailed in the following table

Operation Undefined when

ZeroExtend(x`n)`m m lt nSignExtend(x`n)`m m lt n(x`m)ltpgt m le p(x`m)lthlgt`n n = h+ 1minus l or h lt l orm le h((xm) (yn))`p p = m+ n((x`m) ^ n)`p p = m middot n (which covers n = 0)

The type checker will fail when these conditions are obviously violated Alternatively the inter-preter may raise a runtime error when these conditions are not met

As before the expressions lsquoLog2(0)rsquo lsquox quot 0rsquo lsquox rem 0rsquo lsquox div 0rsquo and lsquox mod 0rsquo are allundefined

A6 Bit-stringsVarious bit-string operation are defined over the type lsquobool listrsquo These are listed below

bit value middot ltmiddotgt bool listtimes nat rarr boolbit field middot ltmiddotmiddotgt bool listtimes nattimes nat rarr bool listconcatenation bool listtimes bool list rarr bool listduplication ^ bool listtimes nat rarr bool listaddition + bool listtimes bool list rarr bool listbitwise conjunction ampamp bool listtimes bool list rarr bool listbitwise disjunction || bool listtimes bool list rarr bool listbitwise exclusive-or bool listtimes bool list rarr bool listleft-shift ltlt bool listtimes nat rarr bool listright-shift gtgt+ bool listtimes nat rarr bool listrotate-right gtgt bool listtimes nat rarr bool list

The bit value operation gives the truth value of a bit-string at a given bit position for example

lsquo0s1101lt0gtrsquo = lsquotruersquo lsquo0s1101lt1gtrsquo = lsquofalsersquo lsquo0s1101lt2gtrsquo = lsquotruersquolsquo0s1101lt3gtrsquo = lsquotruersquo lsquo0s1101lt4gtrsquo = lsquofalsersquo lsquo0s1101lt5gtrsquo = lsquofalsersquo

25

The least-significant bit (position zero) occurs to the right of the bit-string The bit value oper-ation gives lsquofalsersquo when the bit position is greater than the size of the bit-string

The bit field operation extracts a range of bits from a bit-string For example

lsquo0s1101lt31gtrsquo = lsquo0s110rsquo and lsquo0s1101lt52gtrsquo = lsquo0s0011rsquo

In the bit-string expression xlthlgt the size of the result is always h + 1 minus l and the result isundefined when h lt l

Bit-string addition does not require the arguments to be of the same size and it gives anon-truncated result For example

lsquo0s101 + 0s1rsquo = lsquo0s110rsquo and lsquo0s101 + 0s11rsquo = lsquo0s1000rsquo

The operation ltlt performs a left-shift for example lsquo0s1101 ltlt 2rsquo = lsquo0s110100rsquo The oper-ation lsquorsquo is bit-string concatenation and lsquo^rsquo is duplication for example

lsquo0s101 0s11rsquo = lsquo0s10111rsquo and lsquo0s101 ^ 3rsquo = lsquo0s101101101rsquo

Regular list operations work as one would expect over bit-strings for example lsquoHead (0s101)rsquois a valid expression with value lsquotruersquo

A7 Characters and StringsThe following built-in functions are available for characters and strings

is alphabetic IsAlpha char rarr boolis alpha-numeric IsAlphaNum char rarr boolis decimal digit IsDigit char rarr boolis hexadecimal digit IsHexDigit char rarr boolis lowercase IsLower char rarr boolis uppercase IsUpper char rarr boolparse binary FromBinString string rarr num optionparse decimal FromDecString string rarr num optionparse hexadecimal FromHexString string rarr num optionconvert to lowercase ToLower string rarr stringconvert to uppercase ToUpper string rarr string

The following string operations are useful for parsing

split from the left splitl (char rarr bool) times string rarr string times stringsplit from the right splitr (char rarr bool) times string rarr string times stringsplit into fields fields (char rarr bool) times string rarr string listsplit into tokens tokens (char rarr bool) times string rarr string list

These are based on the SML functions Substringsplitl Substringsplitr Stringfieldsand Stringtokens Character predicates are declared using special syntax for example theexpression

splitl space or hexdigit and not in set a f ( 12bcab)

gives the result lsquo( 12bc ab)rsquo

26

A8 Floating-pointThe L3 language does not provide specialised types for representing floating-point numbersHowever 32-bit (single precision) and 64-bit (double precision) bit-vector values can be treatedas floating-point numbers the following IEEE compliant encoding formats are assumed

31 30 23 22 0

s e m1 8 23

63 62 52 51 0

s e m1 11 52

Here lsquosrsquo is the sign bit (set to lsquo1rsquo for negative numbers) lsquoersquo is a biased exponent value and lsquomrsquo is thesignificand The following constants and operations are available (where lsquofprsquo stands for bits(32)or bits(64) depending on the name of the operation)

rounding modes roundTiesToEvenroundTowardPositiveroundTowardNegativeroundTowardZero

ieee_rounding

flags (record) DivideByZero InvalidOpOverflow PrecisionUnderflow

ieee_flagsrarrbool

comparison values FP_LT FP_EQ FP_GT FP_UN ieee_compare

convert format FP32_ToFP64 fp32rarrfp64convert format FP64_ToFP32 ieee_roundingtimes fp64rarrfp32convert format FP64_ToFP32_ ieee_roundingtimes fp64rarr

ieee_flagstimes fp32from integer FP32|64_FromInt ieee_roundingtimes intrarrfpto integer FP32|64_ToInt ieee_roundingtimes fprarrint optionfrom string FP32|64 stringrarrfp

negative zero FP32|64_NegZero fppositive zero FP32|64_PosZero fpnegative infinity FP32|64_NegInf fppositive infinity FP32|64_PosInf fpa quiet NaN FP32|64_qNan fpa signalling NaN FP32|64_sNan fp

is integral FP32|64_IsIntegral fprarrboolis finite FP32|64_IsFinite fprarrboolis NaN FP32|64_IsNan fprarrboolis signalling NaN FP32|64_IsSignallingNan fprarrboolis normal FP32|64_IsNormal fprarrboolis sub-normal FP32|64_IsSubnormal fprarrboolis zero FP32|64_IsZero fprarrbool

27

comparison FP32|64_Compare fptimes fprarrieee_compareequality FP32|64_Equal fptimes fprarrboolless than FP32|64_LessThan fptimes fprarrboolless than or equal FP32|64_LessEqual fptimes fprarrboolgreater than FP32|64_GreaterThan fptimes fprarrboolgreater than or equal FP32|64_GreaterEqual fptimes fprarrbool

absolute FP32|64_Abs fprarrfpnegation FP32|64_Neg fprarrfpsquare root FP32|64_Sqrt ieee_roundingtimes fprarrfp(with flags) FP32|64_Sqrt_ ieee_roundingtimes fprarrieee_flagstimes fpaddition FP32|64_Add ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Add_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpsubtraction FP32|64_Sub ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Sub_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpmultiplication FP32|64_Mul ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Mul_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpfused multiply-add FP32|64_MulAdd ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulAdd_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpfused multiply-sub FP32|64_MulSub ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulSub_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpdivision FP32|64_Div ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Div_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fp

The L3 interpreter supports evaluation for 32-bit and 64-bit floating-point expressions but onlywhen running on an x86 machine that supports SSE2 extensions (Pentium 4 and later) Thefused multiply-addsub operations can only be interpreted on machines supporting the FMAextension which came in with the 4th generation (Haswell) Intel processors These restrictionsalso apply to any Standard ML code that is generated by L3

The IEEE 754 standard permits a number of different ways to flag underflow L3 predomi-nantly supports the x86 interpretation which detects underflow after rounding However whenexporting to HOL4 it is possible to choose detection before rounding which for example issuited to ARM instruction set models

A9 Miscellaneous operationsThe following operations are available

pair constructor αtimes β rarr αtimes βfirst of pair Fst αtimes β rarr αsecond of pair Snd αtimes β rarr β

casting [middot] α rarr βinitialise a map InitMap α rarr (βrarrα)

28

option constructor Some αrarrα optionoption projection ValOf α option rarr αoption test IsSome α option rarr bool

set membership in αtimesα set rarr boolset non-membership notin αtimesα set rarr boolset insertion insert αtimesα set rarrα setset union Union α settimesα set rarrα setset intersection Intersect α settimesα set rarrα setset difference Difference α settimesα set rarrα setset subset test IsSubset α settimesα set rarr boolset cardinality Cardinality α setrarr natset from a list SetOfList α list rarrα set

empty list Nil α listlist constructor Cons αtimesα list rarr α listlist head Head α list rarr αlist tail Tail α list rarr α listlist length Length α list rarr natlist concatenation α listtimesα list rarr α listlist flatten Concat α list list rarr α listlist element Element nattimesα list rarr αlist prefix Take nattimesα list rarr α listlist drop prefix Drop nattimesα list rarr α listlist pad left PadLeft αtimes nattimesα list rarr α listlist pad right PadRight αtimes nattimesα list rarr α listlist update Update αtimes nattimesα list rarr α listlist difference Remove α listtimesα list rarr α listlist intersection RemoveExcept α listtimesα list rarr α listlist without duplicates RemoveDuplicates α listrarr α listlist membership IsMember αtimesα list rarr boollist member position IndexOf αtimesα list rarr nat option

Sets are only defined over equality types see Appendix A2 The casting map is defined overcast-able types (as represented by the polymorphic type variables α and β) these are the primitivetypes (with the exception of lsquounitrsquo) and user defined enumerated types Assume lsquoEnumrsquo and lsquoEnum2rsquoare declared with

construct Enum One Two Three construct Enum2 Four Five Six Seven

The cast operations are described in Tables 1 to 7

29

Table 1 Cast to lsquoboolrsquo

From Operation Examples

bool identity lsquo[true]boolrsquo = lsquotruersquostring parse bool lsquo[true]boolrsquo = lsquotruersquo

lsquo[false]boolrsquo = lsquofalsersquootherwise undefined

nat is not zero lsquo[0n3]boolrsquo = lsquotruersquolsquo[0n0]boolrsquo = lsquofalsersquo

int is not zero lsquo[-0i1]boolrsquo = lsquotruersquolsquo[0i0]boolrsquo = lsquofalsersquo

bool list is not zero lsquo[0s11]boolrsquo = lsquotruersquolsquo[0s0]boolrsquo = lsquofalsersquo

bits(middot) is not zero lsquo[3`3]boolrsquo = lsquotruersquolsquo[0`3]boolrsquo = lsquofalsersquo

Enum is not the first element lsquo[One]boolrsquo = lsquofalsersquolsquo[Two]boolrsquo = lsquotruersquo

Table 2 Cast to lsquostringrsquo

From Operation Examples

bool name lsquo[true]stringrsquo = lsquotruersquostring identity lsquo[hello]stringrsquo = lsquohellorsquonat decimal lsquo[0n3]stringrsquo = lsquo3rsquoint signed decimal lsquo[-0i1]stringrsquo = lsquo~1rsquobool list binary lsquo[0s11]stringrsquo = lsquo11rsquobits(middot) unsigned hexadecimal lsquo[139`8]stringrsquo = lsquo8BrsquoEnum name lsquo[One]stringrsquo = lsquoOnersquo

30

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

115 Instruction Set DefinitionsWhen working with instruction set models it is helpful to construct a datatype that representsthe set of machine (low-level) instructions This datatype constitutes a simple form of abstractsyntax tree (AST) and it can be used to build instruction decoders (identifying machine-codeinstructions and splitting opcodes into sub-fields) instruction encoders (generating opcodes fora given instruction) next-state functions (applying a semantics function for a given instruction)and assembly code parsers

By way of an example consider the MIPS instruction ANDI this instruction has the assemblycode syntax

ANDI rt rs immediate

and the following 32-bit machine-code encoding

31 26 25 21 20 16 15 0

001100 rs rt immediate6 5 5 16

The semantics of this instruction can be expressed with the operation

unit run_ANDI (rsbits(5) rtbits(5) immbits(16)) =GPR(rt) lt- GPR(rs) ampamp ZeroExtend (imm)

One could use this operation to directly specify a next-state function which would be of theform

unit Next =match Fetch -- fetches a 32-bit opcode from memory

middot middot middotcase 001100 rs rt imm =gt run_ANDI (rs rt imm)middot middot middot

This style of specification is direct and concise however it does lack some of the flexibility thatcomes with using an instruction datatype The L3 language provides support for an slightlydifferent style of specification This alternative approach is explained by first examining howone would specify things manually (explicitly) and then showing how L3 can streamline thisprocess

Firstly one could explicitly define an AST datatype for MIPS instructions it would be ofthe form

construct instruction

middot middot middotANDI bits(5) bits(5) bits(16)middot middot middot

14

This datatype provides a suitable constructor for the ANDI instruction It is now possible to definea decoder which maps opcodes onto AST entries for example

instruction Decode (opcbits(32)) =match opc

middot middot middotcase 001100 rs rt imm =gt ANDI (rs rt imm)middot middot middot

This decoder can be used to define our next-state function that is

unit Next = Run (Decode (Fetch))

where lsquoRunrsquo is defined by

unit Run (iinstruction) =match i

middot middot middotcase ANDI (args) =gt run_ANDI (args)middot middot middot

When working with full-scale architecture specifications (where the AST type is large) thereare some clear overheads associated with implementing this approach (in comparison with theAST free version) It becomes challenging to maintain the AST datatype declaration and tokeep it correctly synchronised with the instruction semantics operations (such as lsquorun_ANDIrsquo)and the definition of lsquoRunrsquo Note however that there is great uniformity in the AST datatypedeclaration and also in the definition of lsquoRunrsquo As such L3 is able to automatically define bothof these for the user

To make use of this automation the declaration of lsquorun_ANDIrsquo is simply modified to

define ANDI (rsbits(5) rtbits(5) immbits(16)) =GPR(rt) lt- GPR(rs) ampamp ZeroExtend (imm)

The lsquodefinersquo keyword tells L3 to define a semantics function14 (as before) and to also create anew lsquoinstructionrsquo datatype AST entry furthermore the two will be linked with the automaticconstruction of a lsquoRunrsquo function The lsquoinstructionrsquo type and lsquoRunrsquo function become defined (inscope) following the declaration lsquodefine Runrsquo After this declaration it is no longer possible touse the lsquodefinersquo construct again however it does become possible to define functions such aslsquoDecodersquo and lsquoNextrsquo

Specifications that are based on using lsquodefinersquo gain the benefits of declaring an instructionAST datatype without the downside of laborious coding overheads In the example above theoverhead amounts to one extra line of code this comes from defining a next-state function thatcalls the dedicated decode function followed by a call to lsquoRunrsquo

One of the key advantages of declaring an instruction datatype is that it makes it consider-ably easier to develop tools that work with assembly code syntax (performing parsing encoding

14This function is internally called lsquodfnANDIrsquo instead of lsquorun_ANDIrsquo

15

and pretty-printing) In this case it is relatively easy for example to map between the MIPSinstruction syntax andi $5 $6 1024 and the expression lsquoANDI (5 6 1024)rsquo Defining anencoder in L3 is relatively straightforward for example

bits(32) Encode (iinstruction) =match i

middot middot middotcase ANDI (rs rt imm) =gt 001100 rs rt immmiddot middot middot

Such a function can be used to write a MIPS assembler which would map the assembly codesyntax andi $5 $6 1024 onto the machine-code value 0x30c50400

2 TutorialThis section gives a brief overview of how to install and use L3

Installation The sources for L3 can be downloaded from the following webpage

wwwclcamacuk~acjf3l3

The file l3tarbz2 can be unpacked with the command

$ tar xvjf l3tarbz2

This will create a directory of the form L3-YYYY-MM-DD where the year month and day willcorrespond with the release date The current version of L3 depends upon PolyML 57 whichcan be obtained from the site polymlorg If PolyML is installed then L3 can be built as follows

$ cd L3-YYYY-MM-DD$ make

Once built the following should appear when you start L315

$ l3ltlt L3 gtgtgt

Users should consider running L3 with the command rlwrap l316

15This assumes that the directory L3-YYYY-MM-DDbin has been added to the PATH environment variable16Details on rlwrap utility can be found at the site freecodecomprojectsrlwrap

16

Basic Interaction The command prompt for L3 is essentially the read-eval-print loop (REPL)of PolyML As such users are free to write arbitrary Standard ML code The structure Runtimeenables interaction with L3 The following shows an arithmetic evaluation in Standard ML aswell as in the L3 interpreter (evalQ)

gt 1 + 2val it = 3 intgt RuntimeevalQ `0i1 + 2`val it = `0i3` Termterm

Various error messages can occur when using the interpreter for example

gt RuntimeevalQ `1 + 2`Exception- Fail Could not infer all types raised

gt RuntimeevalQ `0i2 div 0`Exception- Except (Div SOME (div (int [`0i2` `0i0`]))) raised

The first error occurs because unannotated number literals are regarded as bit-vector values andhere the vector width cannot be inferred

L3 declarations can be made using the function loadQ The following sequence shows thedeclaration and manipulation of a global variable

gt RuntimeloadQ `declare n nat`ltVARgt nval it = () unit

gt RuntimeevalQ `n`val it = `UNKNOWNnat` Termterm

gt RuntimeevalQ ` n lt- 3 n `val it = `0n3` Termterm

The global state can be examined using the function show for example

gt Runtimeshow()val it = [(n `0n3`)] Evalterm_stack

The state can be ldquowipedrdquo clean using the function reset and all declarations can be wiped usinglsquoresetAllrsquo for example

gt Runtimereset()val it = () unitgt Runtimeshow()val it = [(n `UNKNOWNnat`)] Evalterm_stack

gt RuntimeresetAll()val it = () unitgt Runtimeshow()val it = [] Evalterm_stack

The function lsquoLoadQrsquo is similar to lsquoloadQrsquo but it performs a lsquoresetAllrsquo before making declarations

17

Constants The structure Consts provides various functions for working with L3 constantsMany of the operation in the Consts structure will be of little interest to end-users however itcan be used to display some helpful information

The function ConstslookupConst can be used to lookup an operation for example

gt ConstslookupConst Log2val it = Primitive [(bits(a) -gt bits(a) -) (nat -gt nat -)] const

Since lsquoLog2rsquo is a primitive operation only the valid types (ordered by overload priority) are showWith user operations the internal representation (definition) of the operation will be shownfor example

gt RuntimeLoadQ `unit demo () = ()`gt ConstslookupConst demoval it = Definition (Abs ([(_ (unit -))] unit -gt unit `()`) NONE 1)

Constsconst

The functions ConstslistDefinitions and ConstslistExceptions provide details of all useroperations and exceptions respectively The function lsquoConstsstatsrsquo gives a summary of all thecurrent declarations

gt Constsstats()Primitives 188Destructors 5Constructors 0Accessors 0Exceptions 0User operations 1Instruction definitions 0

Here the constructors for primitive types (such as lsquoConsrsquo) are counted under ldquoprimitivesrdquo

Types The Types structure can be used to display information relating to L3 types In partic-ular this structure provides the functions TypeslookupConst and TypeslistConsts which aredemonstrated below

gt RuntimeloadQ `construct enum One Two Three`gt TypeslistConsts()val it =

[(enumeq = true ast = false def = Constructors (Enum ltdict(3)gt) num = 0)]

(string typeconst) list

gt TypeslookupConst intval it = SOME eq = true ast = false def = BaseType num = ~1

typeconst option

18

Loading and Exporting Specifications When writing an L3 specification it is expected thatuser declarations will be contained in an L3 source file A sample instruction set specification(tinyspec) can be found in the L3 distribution subdirectory examples This specification isbased on Thackerrsquos pedagogical Tiny 3 architecture it can be loaded as follows

gt RuntimeLoadF tinyspecLoading tinyspecltTYPgt regTltTYPgt wordTmiddot middot middotltFUNgt test_progDone

The string argument to the functions RuntimeloadF and RuntimeLoadF can be in the form ofa comma separated list of files which will be loaded in order That is the call

RuntimeloadF aspec bspec

will load aspec followed by bspecThe function HolExportexport will export the current L3 specification in the form of an

HOL4 script for example

gt HolExportexport tinyraiseexception okfunction okmiddot middot middotmextend skipmunextend skipCreated file tinyScriptsmlCreated file tinyLibsmlCreated file tinyLibsigDone

The function HolExportspec provides a convenient shortcut for performing LoadF and exportusing just a single call for example HolExportspec (tinyspec tiny) will perform theload and export presented above

L3 is capable of exporting two styles of HOL specification an explicitly monadic version(based on state_transformerTheory) and a version that directly manipulates state using let-expressions (which is the default style) For example a monadic version of the Tiny specifi-cation can be exported using the command HolExportspec (tinyspec tiny monadic)Other export options include sigdocs nosigdocs (for setting HOLrsquos TheoryPPinclude_docstrace variable) bigrecords nobigrecords (for controlling HOLrsquos Datatypebig_record_size)and underflowbefore nounderflowbefore (for selecting the required IEEE 754 underflow be-haviour)

Generated HOL4 specifications are not designed to be manually edited (or human readable)To build an L3 specification script the HOL library Import is needed This library is currentlylocated in the directory $HOL_DIRexamplesl3-machine-codecommon and so adding this path tothe INCLUDES variable of a local Holmakefile is recommended The examplesl3-machine-codedirectory contains various examples of using L3 generated specifications

19

Testing Specifications Having written an L3 specification it is fairly easy to write code (inStandard ML) that runs test vectors Code for running the tinyspec example can be found inthe file run-tinyspec In this test harness the Tiny state is initialised and a small test programis loaded simply by evaluating the expression lsquoinitialize (test_prog)rsquo

It is also possible to evaluate (run) models that have been exported to HOL4 The filerun-tinysml shows how this can be accomplished for the Tiny example

20

A Primitive Types and OperationsThe primitive types are as follows

unit bool char nat int bits(middot) rounding

There are two infix type constructors lsquorsquo for pairs and lsquo-gtrsquo for maps There are also postfix typeconstructors lsquosetrsquo lsquooptionrsquo and lsquolistrsquo for example sets of strings are represented by the typelsquostring setrsquo The following sections describe these primitive types together with some detailsof associated operations The following constants and operations are available

nullary () Nil None false roundTiesToEven roundTowardNegativeroundTowardPositive roundTowardZero true

prefix - ~ Abs Cardinality Cons Difference Drop Element FP32_AbsFP32_Add FP32_Equal FP32_IsNan FP32_LessThan FP32_MulFP32_Neg FP32_Sub FP64_Abs FP64_Add FP64_Equal FP64_IsNanFP64_LessThan FP64_Mul FP64_Neg FP64_Sub FromBinStringFromDecString FromHexString Fst Head IndexOf InitMapIntersection IsAlpha IsAlphaNum IsDigit IsHexDigit IsLowerIsMember IsSome IsSubset IsUpper Length Log2 Max Min MsbQuotRem Remove RemoveDuplicates RemoveExcept ReverseSetOfList SignExtend SignedMax SignedMin Size Snd Some TailTake ToLower ToUpper Union Update ValOf ZeroExtend not

infix = ampamp + - lt lt+ lt= lt=+ ltgt == gt gt+ gt= gt=+ ^ || gtgtltlt gtgt+ ltlt gtgt and div in insert mod notin or quot rem

sdivsmodother middot ltmiddotgt middot ltmiddotmiddotgt [middot] fields splitl splitr tokens

Many arithmetic operations are overloaded Unless otherwise stated the order of selection islsquobits(middot)rsquo lsquonatrsquo lsquointrsquo and then lsquobool listrsquo

A1 UnitThe type lsquounitrsquo represents the singleton set containing the value lsquo()rsquo The primary use of thistype is as the return type for procedures

A2 BoolThe type lsquoboolrsquo represents the two element set B = lsquotruersquo lsquofalsersquo The following standardBoolean operations are available

negation not bool rarr boolconjunction and booltimes bool rarr booldisjunction or booltimes bool rarr boolequality == αtimesα rarr boolnon-equality ltgt = αtimesα rarr bool

21

The infix operators lsquoandrsquo and lsquoorrsquo are interpreted with short-circuit evaluation for example in theexpression lsquofalse and f()rsquo the value of lsquof()rsquo is not computed as the overall expression will alwaysevaluate to false This short-circuiting influences the side-effects that occur during expressionevaluation

There are two prefix symbols for logical negation (these are semantically identical) with lsquorsquobinding slightly tighter than lsquonotrsquo This distinction is becomes significant when working withequalities for example lsquonot a == brsquo is taken to be not(a = b) whereas lsquoa == brsquo is (nota) = b

Equality is only defined with respect to equality types represented here by the type variableα An equality type is any type built without the used of the map operator lsquo-gtrsquo

A3 NatThe type lsquonatrsquo represents the natural numbers N = 0 1 2 The following operations areavailable

logarithm (base two) Log2 nat rarr natminimum value Min nattimes nat rarr natmaximium value Max nattimes nat rarr natless than lt nattimes nat rarr boolgreater than gt nattimes nat rarr boolless than or equal to lt= nattimes nat rarr boolgreater than or equal to gt= nattimes nat rarr booladdition + nattimes nat rarr natsubtraction - nattimes nat rarr natmultiplication nattimes nat rarr natexponentiation nattimes nat rarr natdivision div nattimes nat rarr natmodulus mod nattimes nat rarr nat

The lsquodivrsquo and lsquomodrsquo operations satisfy the following property

foralln 0 lt n =rArr forallk k = (k div n) lowast n+ (k mod n) and (k mod n) lt n

The expressions lsquoLog2(0)rsquo lsquox div 0rsquo and lsquox mod 0rsquo are all undefined 17

A4 IntThe type lsquointrsquo represents the integers Z = Ncupminus1minus2minus3 The following operations areavailable

17The interpreter will raise an exception when attempting to evaluate them

22

unary minus - int rarr intabsolute value Abs int rarr intminimum value Min inttimes int rarr intmaximum value Max inttimes int rarr intless than lt inttimes int rarr boolgreater than gt inttimes int rarr boolless than or equal to lt= inttimes int rarr boolgreater than or equal to gt= inttimes int rarr booladdition + inttimes int rarr intsubtraction - inttimes int rarr intmultiplication inttimes int rarr intexponentiation inttimes nat rarr intquotient and remainder QuotRem inttimes int rarr inttimes intquotient quot inttimes int rarr intremainder rem inttimes int rarr intdivision div inttimes int rarr intmodulus mod inttimes int rarr int

The operation lsquoAbsrsquo gives an positive integer value for example lsquoAbs(-2)rsquo = lsquo2rsquo The integeroperations lsquoquotrsquo and lsquodivrsquo are related to natural number division as follows

i quot j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

and

i div j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(minusi) div n(j))minus 1 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i and n(i) mod n(minusj) = 0

minus z(n(i) div n(minusj))minus 1 j lt 0 and 0 le i and n(i) mod n(minusj) = 0

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

where z NrarrZ and n ZrarrN are value preserving maps The lsquoremrsquo and lsquomodrsquo operations satisfythe equations

i rem j =

iminus (i quot j) lowast j j = 0

undefined j = 0i mod j =

iminus (i div j) lowast j j = 0

undefined j = 0

A5 Bit-vectorsThe type lsquobits(n)rsquo represents fixed-width (n-bit) words also known as bit-vectors for examplebits(32) is the type of 32-bit machine words18 The bits type can be viewed as representing

18These are called double-words (dword) in the x86 architecture and simply words in the ARM architecture

23

the set Zn = 0 1 2nminus1 for some 0 lt n At the type system level no distinction is madebetween signed and unsigned words however some operations (such as orderings) have signedand unsigned variants

The following bit-vector operations are available

1rsquos complement ~ bits(n) rarr bits(n)2rsquos complement - bits(n) rarr bits(n)absolute value Abs bits(n) rarr bits(n)logarithm (base two) Log2 bits(n) rarr bits(n)zero-extend ZeroExtend bits(m) rarr bits(n)sign-extend SignExtend bits(m) rarr bits(n)reverse bits Reverse bits(n) rarr bits(n)minimum value (u) Min bits(n)times bits(n) rarr bits(n)maximum value (u) Max bits(n)times bits(n) rarr bits(n)minimum value (s) SignedMin bits(n)times bits(n) rarr bits(n)maximum value (s) SignedMax bits(n)times bits(n) rarr bits(n)widthsize Size bits(n) rarr natmost-significant (sign) bit Msb bits(n) rarr boolbit value middot ltmiddotgt bits(n)times nat rarr boolbit field middot ltmiddotmiddotgt bits(m)times nattimes nat rarr bits(n)concatenation bits(m)times bits(n) rarr bits(p)duplication ^ bits(m)times nat rarr bits(n)less than (s) lt bits(n)times bits(n) rarr boolgreater than (s) gt bits(n)times bits(n) rarr boolless than or equal to (s) lt= bits(n)times bits(n) rarr boolgreater than or equal to (s) gt= bits(n)times bits(n) rarr boolless than (u) lt+ bits(n)times bits(n) rarr boolgreater than (u) gt+ bits(n)times bits(n) rarr boolless than or equal to (u) lt=+ bits(n)times bits(n) rarr boolgreater than or equal to (u) gt=+ bits(n)times bits(n) rarr booladdition + bits(n)times bits(n) rarr bits(n)subtraction - bits(n)times bits(n) rarr bits(n)multiplication bits(n)times bits(n) rarr bits(n)quotient (s) quot bits(n)times bits(n) rarr bits(n)remained (s) rem bits(n)times bits(n) rarr bits(n)division (u) div bits(n)times bits(n) rarr bits(n)modulus (u) mod bits(n)times bits(n) rarr bits(n)division (s) sdiv bits(n)times bits(n) rarr bits(n)modulus (s) smod bits(n)times bits(n) rarr bits(n)bitwise conjunction ampamp bits(n)times bits(n) rarr bits(n)bitwise disjunction || bits(n)times bits(n) rarr bits(n)bitwise exclusive-or bits(n)times bits(n) rarr bits(n)

Unsigned operations are labelled with (u) and signed operations are labelled with (s)The shift operations support shifting by either a bit-vector value or by a natural number value

The overloading is resolved such that the lsquonatrsquo variant is selected over the lsquobits(middot)rsquo version Theshift operations are

24

left-shift ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (u) gtgt+ bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (s) gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate left ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate right gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

A number of operations are undefined depending on the types of their domain and rangeThis is detailed in the following table

Operation Undefined when

ZeroExtend(x`n)`m m lt nSignExtend(x`n)`m m lt n(x`m)ltpgt m le p(x`m)lthlgt`n n = h+ 1minus l or h lt l orm le h((xm) (yn))`p p = m+ n((x`m) ^ n)`p p = m middot n (which covers n = 0)

The type checker will fail when these conditions are obviously violated Alternatively the inter-preter may raise a runtime error when these conditions are not met

As before the expressions lsquoLog2(0)rsquo lsquox quot 0rsquo lsquox rem 0rsquo lsquox div 0rsquo and lsquox mod 0rsquo are allundefined

A6 Bit-stringsVarious bit-string operation are defined over the type lsquobool listrsquo These are listed below

bit value middot ltmiddotgt bool listtimes nat rarr boolbit field middot ltmiddotmiddotgt bool listtimes nattimes nat rarr bool listconcatenation bool listtimes bool list rarr bool listduplication ^ bool listtimes nat rarr bool listaddition + bool listtimes bool list rarr bool listbitwise conjunction ampamp bool listtimes bool list rarr bool listbitwise disjunction || bool listtimes bool list rarr bool listbitwise exclusive-or bool listtimes bool list rarr bool listleft-shift ltlt bool listtimes nat rarr bool listright-shift gtgt+ bool listtimes nat rarr bool listrotate-right gtgt bool listtimes nat rarr bool list

The bit value operation gives the truth value of a bit-string at a given bit position for example

lsquo0s1101lt0gtrsquo = lsquotruersquo lsquo0s1101lt1gtrsquo = lsquofalsersquo lsquo0s1101lt2gtrsquo = lsquotruersquolsquo0s1101lt3gtrsquo = lsquotruersquo lsquo0s1101lt4gtrsquo = lsquofalsersquo lsquo0s1101lt5gtrsquo = lsquofalsersquo

25

The least-significant bit (position zero) occurs to the right of the bit-string The bit value oper-ation gives lsquofalsersquo when the bit position is greater than the size of the bit-string

The bit field operation extracts a range of bits from a bit-string For example

lsquo0s1101lt31gtrsquo = lsquo0s110rsquo and lsquo0s1101lt52gtrsquo = lsquo0s0011rsquo

In the bit-string expression xlthlgt the size of the result is always h + 1 minus l and the result isundefined when h lt l

Bit-string addition does not require the arguments to be of the same size and it gives anon-truncated result For example

lsquo0s101 + 0s1rsquo = lsquo0s110rsquo and lsquo0s101 + 0s11rsquo = lsquo0s1000rsquo

The operation ltlt performs a left-shift for example lsquo0s1101 ltlt 2rsquo = lsquo0s110100rsquo The oper-ation lsquorsquo is bit-string concatenation and lsquo^rsquo is duplication for example

lsquo0s101 0s11rsquo = lsquo0s10111rsquo and lsquo0s101 ^ 3rsquo = lsquo0s101101101rsquo

Regular list operations work as one would expect over bit-strings for example lsquoHead (0s101)rsquois a valid expression with value lsquotruersquo

A7 Characters and StringsThe following built-in functions are available for characters and strings

is alphabetic IsAlpha char rarr boolis alpha-numeric IsAlphaNum char rarr boolis decimal digit IsDigit char rarr boolis hexadecimal digit IsHexDigit char rarr boolis lowercase IsLower char rarr boolis uppercase IsUpper char rarr boolparse binary FromBinString string rarr num optionparse decimal FromDecString string rarr num optionparse hexadecimal FromHexString string rarr num optionconvert to lowercase ToLower string rarr stringconvert to uppercase ToUpper string rarr string

The following string operations are useful for parsing

split from the left splitl (char rarr bool) times string rarr string times stringsplit from the right splitr (char rarr bool) times string rarr string times stringsplit into fields fields (char rarr bool) times string rarr string listsplit into tokens tokens (char rarr bool) times string rarr string list

These are based on the SML functions Substringsplitl Substringsplitr Stringfieldsand Stringtokens Character predicates are declared using special syntax for example theexpression

splitl space or hexdigit and not in set a f ( 12bcab)

gives the result lsquo( 12bc ab)rsquo

26

A8 Floating-pointThe L3 language does not provide specialised types for representing floating-point numbersHowever 32-bit (single precision) and 64-bit (double precision) bit-vector values can be treatedas floating-point numbers the following IEEE compliant encoding formats are assumed

31 30 23 22 0

s e m1 8 23

63 62 52 51 0

s e m1 11 52

Here lsquosrsquo is the sign bit (set to lsquo1rsquo for negative numbers) lsquoersquo is a biased exponent value and lsquomrsquo is thesignificand The following constants and operations are available (where lsquofprsquo stands for bits(32)or bits(64) depending on the name of the operation)

rounding modes roundTiesToEvenroundTowardPositiveroundTowardNegativeroundTowardZero

ieee_rounding

flags (record) DivideByZero InvalidOpOverflow PrecisionUnderflow

ieee_flagsrarrbool

comparison values FP_LT FP_EQ FP_GT FP_UN ieee_compare

convert format FP32_ToFP64 fp32rarrfp64convert format FP64_ToFP32 ieee_roundingtimes fp64rarrfp32convert format FP64_ToFP32_ ieee_roundingtimes fp64rarr

ieee_flagstimes fp32from integer FP32|64_FromInt ieee_roundingtimes intrarrfpto integer FP32|64_ToInt ieee_roundingtimes fprarrint optionfrom string FP32|64 stringrarrfp

negative zero FP32|64_NegZero fppositive zero FP32|64_PosZero fpnegative infinity FP32|64_NegInf fppositive infinity FP32|64_PosInf fpa quiet NaN FP32|64_qNan fpa signalling NaN FP32|64_sNan fp

is integral FP32|64_IsIntegral fprarrboolis finite FP32|64_IsFinite fprarrboolis NaN FP32|64_IsNan fprarrboolis signalling NaN FP32|64_IsSignallingNan fprarrboolis normal FP32|64_IsNormal fprarrboolis sub-normal FP32|64_IsSubnormal fprarrboolis zero FP32|64_IsZero fprarrbool

27

comparison FP32|64_Compare fptimes fprarrieee_compareequality FP32|64_Equal fptimes fprarrboolless than FP32|64_LessThan fptimes fprarrboolless than or equal FP32|64_LessEqual fptimes fprarrboolgreater than FP32|64_GreaterThan fptimes fprarrboolgreater than or equal FP32|64_GreaterEqual fptimes fprarrbool

absolute FP32|64_Abs fprarrfpnegation FP32|64_Neg fprarrfpsquare root FP32|64_Sqrt ieee_roundingtimes fprarrfp(with flags) FP32|64_Sqrt_ ieee_roundingtimes fprarrieee_flagstimes fpaddition FP32|64_Add ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Add_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpsubtraction FP32|64_Sub ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Sub_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpmultiplication FP32|64_Mul ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Mul_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpfused multiply-add FP32|64_MulAdd ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulAdd_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpfused multiply-sub FP32|64_MulSub ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulSub_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpdivision FP32|64_Div ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Div_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fp

The L3 interpreter supports evaluation for 32-bit and 64-bit floating-point expressions but onlywhen running on an x86 machine that supports SSE2 extensions (Pentium 4 and later) Thefused multiply-addsub operations can only be interpreted on machines supporting the FMAextension which came in with the 4th generation (Haswell) Intel processors These restrictionsalso apply to any Standard ML code that is generated by L3

The IEEE 754 standard permits a number of different ways to flag underflow L3 predomi-nantly supports the x86 interpretation which detects underflow after rounding However whenexporting to HOL4 it is possible to choose detection before rounding which for example issuited to ARM instruction set models

A9 Miscellaneous operationsThe following operations are available

pair constructor αtimes β rarr αtimes βfirst of pair Fst αtimes β rarr αsecond of pair Snd αtimes β rarr β

casting [middot] α rarr βinitialise a map InitMap α rarr (βrarrα)

28

option constructor Some αrarrα optionoption projection ValOf α option rarr αoption test IsSome α option rarr bool

set membership in αtimesα set rarr boolset non-membership notin αtimesα set rarr boolset insertion insert αtimesα set rarrα setset union Union α settimesα set rarrα setset intersection Intersect α settimesα set rarrα setset difference Difference α settimesα set rarrα setset subset test IsSubset α settimesα set rarr boolset cardinality Cardinality α setrarr natset from a list SetOfList α list rarrα set

empty list Nil α listlist constructor Cons αtimesα list rarr α listlist head Head α list rarr αlist tail Tail α list rarr α listlist length Length α list rarr natlist concatenation α listtimesα list rarr α listlist flatten Concat α list list rarr α listlist element Element nattimesα list rarr αlist prefix Take nattimesα list rarr α listlist drop prefix Drop nattimesα list rarr α listlist pad left PadLeft αtimes nattimesα list rarr α listlist pad right PadRight αtimes nattimesα list rarr α listlist update Update αtimes nattimesα list rarr α listlist difference Remove α listtimesα list rarr α listlist intersection RemoveExcept α listtimesα list rarr α listlist without duplicates RemoveDuplicates α listrarr α listlist membership IsMember αtimesα list rarr boollist member position IndexOf αtimesα list rarr nat option

Sets are only defined over equality types see Appendix A2 The casting map is defined overcast-able types (as represented by the polymorphic type variables α and β) these are the primitivetypes (with the exception of lsquounitrsquo) and user defined enumerated types Assume lsquoEnumrsquo and lsquoEnum2rsquoare declared with

construct Enum One Two Three construct Enum2 Four Five Six Seven

The cast operations are described in Tables 1 to 7

29

Table 1 Cast to lsquoboolrsquo

From Operation Examples

bool identity lsquo[true]boolrsquo = lsquotruersquostring parse bool lsquo[true]boolrsquo = lsquotruersquo

lsquo[false]boolrsquo = lsquofalsersquootherwise undefined

nat is not zero lsquo[0n3]boolrsquo = lsquotruersquolsquo[0n0]boolrsquo = lsquofalsersquo

int is not zero lsquo[-0i1]boolrsquo = lsquotruersquolsquo[0i0]boolrsquo = lsquofalsersquo

bool list is not zero lsquo[0s11]boolrsquo = lsquotruersquolsquo[0s0]boolrsquo = lsquofalsersquo

bits(middot) is not zero lsquo[3`3]boolrsquo = lsquotruersquolsquo[0`3]boolrsquo = lsquofalsersquo

Enum is not the first element lsquo[One]boolrsquo = lsquofalsersquolsquo[Two]boolrsquo = lsquotruersquo

Table 2 Cast to lsquostringrsquo

From Operation Examples

bool name lsquo[true]stringrsquo = lsquotruersquostring identity lsquo[hello]stringrsquo = lsquohellorsquonat decimal lsquo[0n3]stringrsquo = lsquo3rsquoint signed decimal lsquo[-0i1]stringrsquo = lsquo~1rsquobool list binary lsquo[0s11]stringrsquo = lsquo11rsquobits(middot) unsigned hexadecimal lsquo[139`8]stringrsquo = lsquo8BrsquoEnum name lsquo[One]stringrsquo = lsquoOnersquo

30

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

This datatype provides a suitable constructor for the ANDI instruction It is now possible to definea decoder which maps opcodes onto AST entries for example

instruction Decode (opcbits(32)) =match opc

middot middot middotcase 001100 rs rt imm =gt ANDI (rs rt imm)middot middot middot

This decoder can be used to define our next-state function that is

unit Next = Run (Decode (Fetch))

where lsquoRunrsquo is defined by

unit Run (iinstruction) =match i

middot middot middotcase ANDI (args) =gt run_ANDI (args)middot middot middot

When working with full-scale architecture specifications (where the AST type is large) thereare some clear overheads associated with implementing this approach (in comparison with theAST free version) It becomes challenging to maintain the AST datatype declaration and tokeep it correctly synchronised with the instruction semantics operations (such as lsquorun_ANDIrsquo)and the definition of lsquoRunrsquo Note however that there is great uniformity in the AST datatypedeclaration and also in the definition of lsquoRunrsquo As such L3 is able to automatically define bothof these for the user

To make use of this automation the declaration of lsquorun_ANDIrsquo is simply modified to

define ANDI (rsbits(5) rtbits(5) immbits(16)) =GPR(rt) lt- GPR(rs) ampamp ZeroExtend (imm)

The lsquodefinersquo keyword tells L3 to define a semantics function14 (as before) and to also create anew lsquoinstructionrsquo datatype AST entry furthermore the two will be linked with the automaticconstruction of a lsquoRunrsquo function The lsquoinstructionrsquo type and lsquoRunrsquo function become defined (inscope) following the declaration lsquodefine Runrsquo After this declaration it is no longer possible touse the lsquodefinersquo construct again however it does become possible to define functions such aslsquoDecodersquo and lsquoNextrsquo

Specifications that are based on using lsquodefinersquo gain the benefits of declaring an instructionAST datatype without the downside of laborious coding overheads In the example above theoverhead amounts to one extra line of code this comes from defining a next-state function thatcalls the dedicated decode function followed by a call to lsquoRunrsquo

One of the key advantages of declaring an instruction datatype is that it makes it consider-ably easier to develop tools that work with assembly code syntax (performing parsing encoding

14This function is internally called lsquodfnANDIrsquo instead of lsquorun_ANDIrsquo

15

and pretty-printing) In this case it is relatively easy for example to map between the MIPSinstruction syntax andi $5 $6 1024 and the expression lsquoANDI (5 6 1024)rsquo Defining anencoder in L3 is relatively straightforward for example

bits(32) Encode (iinstruction) =match i

middot middot middotcase ANDI (rs rt imm) =gt 001100 rs rt immmiddot middot middot

Such a function can be used to write a MIPS assembler which would map the assembly codesyntax andi $5 $6 1024 onto the machine-code value 0x30c50400

2 TutorialThis section gives a brief overview of how to install and use L3

Installation The sources for L3 can be downloaded from the following webpage

wwwclcamacuk~acjf3l3

The file l3tarbz2 can be unpacked with the command

$ tar xvjf l3tarbz2

This will create a directory of the form L3-YYYY-MM-DD where the year month and day willcorrespond with the release date The current version of L3 depends upon PolyML 57 whichcan be obtained from the site polymlorg If PolyML is installed then L3 can be built as follows

$ cd L3-YYYY-MM-DD$ make

Once built the following should appear when you start L315

$ l3ltlt L3 gtgtgt

Users should consider running L3 with the command rlwrap l316

15This assumes that the directory L3-YYYY-MM-DDbin has been added to the PATH environment variable16Details on rlwrap utility can be found at the site freecodecomprojectsrlwrap

16

Basic Interaction The command prompt for L3 is essentially the read-eval-print loop (REPL)of PolyML As such users are free to write arbitrary Standard ML code The structure Runtimeenables interaction with L3 The following shows an arithmetic evaluation in Standard ML aswell as in the L3 interpreter (evalQ)

gt 1 + 2val it = 3 intgt RuntimeevalQ `0i1 + 2`val it = `0i3` Termterm

Various error messages can occur when using the interpreter for example

gt RuntimeevalQ `1 + 2`Exception- Fail Could not infer all types raised

gt RuntimeevalQ `0i2 div 0`Exception- Except (Div SOME (div (int [`0i2` `0i0`]))) raised

The first error occurs because unannotated number literals are regarded as bit-vector values andhere the vector width cannot be inferred

L3 declarations can be made using the function loadQ The following sequence shows thedeclaration and manipulation of a global variable

gt RuntimeloadQ `declare n nat`ltVARgt nval it = () unit

gt RuntimeevalQ `n`val it = `UNKNOWNnat` Termterm

gt RuntimeevalQ ` n lt- 3 n `val it = `0n3` Termterm

The global state can be examined using the function show for example

gt Runtimeshow()val it = [(n `0n3`)] Evalterm_stack

The state can be ldquowipedrdquo clean using the function reset and all declarations can be wiped usinglsquoresetAllrsquo for example

gt Runtimereset()val it = () unitgt Runtimeshow()val it = [(n `UNKNOWNnat`)] Evalterm_stack

gt RuntimeresetAll()val it = () unitgt Runtimeshow()val it = [] Evalterm_stack

The function lsquoLoadQrsquo is similar to lsquoloadQrsquo but it performs a lsquoresetAllrsquo before making declarations

17

Constants The structure Consts provides various functions for working with L3 constantsMany of the operation in the Consts structure will be of little interest to end-users however itcan be used to display some helpful information

The function ConstslookupConst can be used to lookup an operation for example

gt ConstslookupConst Log2val it = Primitive [(bits(a) -gt bits(a) -) (nat -gt nat -)] const

Since lsquoLog2rsquo is a primitive operation only the valid types (ordered by overload priority) are showWith user operations the internal representation (definition) of the operation will be shownfor example

gt RuntimeLoadQ `unit demo () = ()`gt ConstslookupConst demoval it = Definition (Abs ([(_ (unit -))] unit -gt unit `()`) NONE 1)

Constsconst

The functions ConstslistDefinitions and ConstslistExceptions provide details of all useroperations and exceptions respectively The function lsquoConstsstatsrsquo gives a summary of all thecurrent declarations

gt Constsstats()Primitives 188Destructors 5Constructors 0Accessors 0Exceptions 0User operations 1Instruction definitions 0

Here the constructors for primitive types (such as lsquoConsrsquo) are counted under ldquoprimitivesrdquo

Types The Types structure can be used to display information relating to L3 types In partic-ular this structure provides the functions TypeslookupConst and TypeslistConsts which aredemonstrated below

gt RuntimeloadQ `construct enum One Two Three`gt TypeslistConsts()val it =

[(enumeq = true ast = false def = Constructors (Enum ltdict(3)gt) num = 0)]

(string typeconst) list

gt TypeslookupConst intval it = SOME eq = true ast = false def = BaseType num = ~1

typeconst option

18

Loading and Exporting Specifications When writing an L3 specification it is expected thatuser declarations will be contained in an L3 source file A sample instruction set specification(tinyspec) can be found in the L3 distribution subdirectory examples This specification isbased on Thackerrsquos pedagogical Tiny 3 architecture it can be loaded as follows

gt RuntimeLoadF tinyspecLoading tinyspecltTYPgt regTltTYPgt wordTmiddot middot middotltFUNgt test_progDone

The string argument to the functions RuntimeloadF and RuntimeLoadF can be in the form ofa comma separated list of files which will be loaded in order That is the call

RuntimeloadF aspec bspec

will load aspec followed by bspecThe function HolExportexport will export the current L3 specification in the form of an

HOL4 script for example

gt HolExportexport tinyraiseexception okfunction okmiddot middot middotmextend skipmunextend skipCreated file tinyScriptsmlCreated file tinyLibsmlCreated file tinyLibsigDone

The function HolExportspec provides a convenient shortcut for performing LoadF and exportusing just a single call for example HolExportspec (tinyspec tiny) will perform theload and export presented above

L3 is capable of exporting two styles of HOL specification an explicitly monadic version(based on state_transformerTheory) and a version that directly manipulates state using let-expressions (which is the default style) For example a monadic version of the Tiny specifi-cation can be exported using the command HolExportspec (tinyspec tiny monadic)Other export options include sigdocs nosigdocs (for setting HOLrsquos TheoryPPinclude_docstrace variable) bigrecords nobigrecords (for controlling HOLrsquos Datatypebig_record_size)and underflowbefore nounderflowbefore (for selecting the required IEEE 754 underflow be-haviour)

Generated HOL4 specifications are not designed to be manually edited (or human readable)To build an L3 specification script the HOL library Import is needed This library is currentlylocated in the directory $HOL_DIRexamplesl3-machine-codecommon and so adding this path tothe INCLUDES variable of a local Holmakefile is recommended The examplesl3-machine-codedirectory contains various examples of using L3 generated specifications

19

Testing Specifications Having written an L3 specification it is fairly easy to write code (inStandard ML) that runs test vectors Code for running the tinyspec example can be found inthe file run-tinyspec In this test harness the Tiny state is initialised and a small test programis loaded simply by evaluating the expression lsquoinitialize (test_prog)rsquo

It is also possible to evaluate (run) models that have been exported to HOL4 The filerun-tinysml shows how this can be accomplished for the Tiny example

20

A Primitive Types and OperationsThe primitive types are as follows

unit bool char nat int bits(middot) rounding

There are two infix type constructors lsquorsquo for pairs and lsquo-gtrsquo for maps There are also postfix typeconstructors lsquosetrsquo lsquooptionrsquo and lsquolistrsquo for example sets of strings are represented by the typelsquostring setrsquo The following sections describe these primitive types together with some detailsof associated operations The following constants and operations are available

nullary () Nil None false roundTiesToEven roundTowardNegativeroundTowardPositive roundTowardZero true

prefix - ~ Abs Cardinality Cons Difference Drop Element FP32_AbsFP32_Add FP32_Equal FP32_IsNan FP32_LessThan FP32_MulFP32_Neg FP32_Sub FP64_Abs FP64_Add FP64_Equal FP64_IsNanFP64_LessThan FP64_Mul FP64_Neg FP64_Sub FromBinStringFromDecString FromHexString Fst Head IndexOf InitMapIntersection IsAlpha IsAlphaNum IsDigit IsHexDigit IsLowerIsMember IsSome IsSubset IsUpper Length Log2 Max Min MsbQuotRem Remove RemoveDuplicates RemoveExcept ReverseSetOfList SignExtend SignedMax SignedMin Size Snd Some TailTake ToLower ToUpper Union Update ValOf ZeroExtend not

infix = ampamp + - lt lt+ lt= lt=+ ltgt == gt gt+ gt= gt=+ ^ || gtgtltlt gtgt+ ltlt gtgt and div in insert mod notin or quot rem

sdivsmodother middot ltmiddotgt middot ltmiddotmiddotgt [middot] fields splitl splitr tokens

Many arithmetic operations are overloaded Unless otherwise stated the order of selection islsquobits(middot)rsquo lsquonatrsquo lsquointrsquo and then lsquobool listrsquo

A1 UnitThe type lsquounitrsquo represents the singleton set containing the value lsquo()rsquo The primary use of thistype is as the return type for procedures

A2 BoolThe type lsquoboolrsquo represents the two element set B = lsquotruersquo lsquofalsersquo The following standardBoolean operations are available

negation not bool rarr boolconjunction and booltimes bool rarr booldisjunction or booltimes bool rarr boolequality == αtimesα rarr boolnon-equality ltgt = αtimesα rarr bool

21

The infix operators lsquoandrsquo and lsquoorrsquo are interpreted with short-circuit evaluation for example in theexpression lsquofalse and f()rsquo the value of lsquof()rsquo is not computed as the overall expression will alwaysevaluate to false This short-circuiting influences the side-effects that occur during expressionevaluation

There are two prefix symbols for logical negation (these are semantically identical) with lsquorsquobinding slightly tighter than lsquonotrsquo This distinction is becomes significant when working withequalities for example lsquonot a == brsquo is taken to be not(a = b) whereas lsquoa == brsquo is (nota) = b

Equality is only defined with respect to equality types represented here by the type variableα An equality type is any type built without the used of the map operator lsquo-gtrsquo

A3 NatThe type lsquonatrsquo represents the natural numbers N = 0 1 2 The following operations areavailable

logarithm (base two) Log2 nat rarr natminimum value Min nattimes nat rarr natmaximium value Max nattimes nat rarr natless than lt nattimes nat rarr boolgreater than gt nattimes nat rarr boolless than or equal to lt= nattimes nat rarr boolgreater than or equal to gt= nattimes nat rarr booladdition + nattimes nat rarr natsubtraction - nattimes nat rarr natmultiplication nattimes nat rarr natexponentiation nattimes nat rarr natdivision div nattimes nat rarr natmodulus mod nattimes nat rarr nat

The lsquodivrsquo and lsquomodrsquo operations satisfy the following property

foralln 0 lt n =rArr forallk k = (k div n) lowast n+ (k mod n) and (k mod n) lt n

The expressions lsquoLog2(0)rsquo lsquox div 0rsquo and lsquox mod 0rsquo are all undefined 17

A4 IntThe type lsquointrsquo represents the integers Z = Ncupminus1minus2minus3 The following operations areavailable

17The interpreter will raise an exception when attempting to evaluate them

22

unary minus - int rarr intabsolute value Abs int rarr intminimum value Min inttimes int rarr intmaximum value Max inttimes int rarr intless than lt inttimes int rarr boolgreater than gt inttimes int rarr boolless than or equal to lt= inttimes int rarr boolgreater than or equal to gt= inttimes int rarr booladdition + inttimes int rarr intsubtraction - inttimes int rarr intmultiplication inttimes int rarr intexponentiation inttimes nat rarr intquotient and remainder QuotRem inttimes int rarr inttimes intquotient quot inttimes int rarr intremainder rem inttimes int rarr intdivision div inttimes int rarr intmodulus mod inttimes int rarr int

The operation lsquoAbsrsquo gives an positive integer value for example lsquoAbs(-2)rsquo = lsquo2rsquo The integeroperations lsquoquotrsquo and lsquodivrsquo are related to natural number division as follows

i quot j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

and

i div j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(minusi) div n(j))minus 1 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i and n(i) mod n(minusj) = 0

minus z(n(i) div n(minusj))minus 1 j lt 0 and 0 le i and n(i) mod n(minusj) = 0

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

where z NrarrZ and n ZrarrN are value preserving maps The lsquoremrsquo and lsquomodrsquo operations satisfythe equations

i rem j =

iminus (i quot j) lowast j j = 0

undefined j = 0i mod j =

iminus (i div j) lowast j j = 0

undefined j = 0

A5 Bit-vectorsThe type lsquobits(n)rsquo represents fixed-width (n-bit) words also known as bit-vectors for examplebits(32) is the type of 32-bit machine words18 The bits type can be viewed as representing

18These are called double-words (dword) in the x86 architecture and simply words in the ARM architecture

23

the set Zn = 0 1 2nminus1 for some 0 lt n At the type system level no distinction is madebetween signed and unsigned words however some operations (such as orderings) have signedand unsigned variants

The following bit-vector operations are available

1rsquos complement ~ bits(n) rarr bits(n)2rsquos complement - bits(n) rarr bits(n)absolute value Abs bits(n) rarr bits(n)logarithm (base two) Log2 bits(n) rarr bits(n)zero-extend ZeroExtend bits(m) rarr bits(n)sign-extend SignExtend bits(m) rarr bits(n)reverse bits Reverse bits(n) rarr bits(n)minimum value (u) Min bits(n)times bits(n) rarr bits(n)maximum value (u) Max bits(n)times bits(n) rarr bits(n)minimum value (s) SignedMin bits(n)times bits(n) rarr bits(n)maximum value (s) SignedMax bits(n)times bits(n) rarr bits(n)widthsize Size bits(n) rarr natmost-significant (sign) bit Msb bits(n) rarr boolbit value middot ltmiddotgt bits(n)times nat rarr boolbit field middot ltmiddotmiddotgt bits(m)times nattimes nat rarr bits(n)concatenation bits(m)times bits(n) rarr bits(p)duplication ^ bits(m)times nat rarr bits(n)less than (s) lt bits(n)times bits(n) rarr boolgreater than (s) gt bits(n)times bits(n) rarr boolless than or equal to (s) lt= bits(n)times bits(n) rarr boolgreater than or equal to (s) gt= bits(n)times bits(n) rarr boolless than (u) lt+ bits(n)times bits(n) rarr boolgreater than (u) gt+ bits(n)times bits(n) rarr boolless than or equal to (u) lt=+ bits(n)times bits(n) rarr boolgreater than or equal to (u) gt=+ bits(n)times bits(n) rarr booladdition + bits(n)times bits(n) rarr bits(n)subtraction - bits(n)times bits(n) rarr bits(n)multiplication bits(n)times bits(n) rarr bits(n)quotient (s) quot bits(n)times bits(n) rarr bits(n)remained (s) rem bits(n)times bits(n) rarr bits(n)division (u) div bits(n)times bits(n) rarr bits(n)modulus (u) mod bits(n)times bits(n) rarr bits(n)division (s) sdiv bits(n)times bits(n) rarr bits(n)modulus (s) smod bits(n)times bits(n) rarr bits(n)bitwise conjunction ampamp bits(n)times bits(n) rarr bits(n)bitwise disjunction || bits(n)times bits(n) rarr bits(n)bitwise exclusive-or bits(n)times bits(n) rarr bits(n)

Unsigned operations are labelled with (u) and signed operations are labelled with (s)The shift operations support shifting by either a bit-vector value or by a natural number value

The overloading is resolved such that the lsquonatrsquo variant is selected over the lsquobits(middot)rsquo version Theshift operations are

24

left-shift ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (u) gtgt+ bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (s) gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate left ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate right gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

A number of operations are undefined depending on the types of their domain and rangeThis is detailed in the following table

Operation Undefined when

ZeroExtend(x`n)`m m lt nSignExtend(x`n)`m m lt n(x`m)ltpgt m le p(x`m)lthlgt`n n = h+ 1minus l or h lt l orm le h((xm) (yn))`p p = m+ n((x`m) ^ n)`p p = m middot n (which covers n = 0)

The type checker will fail when these conditions are obviously violated Alternatively the inter-preter may raise a runtime error when these conditions are not met

As before the expressions lsquoLog2(0)rsquo lsquox quot 0rsquo lsquox rem 0rsquo lsquox div 0rsquo and lsquox mod 0rsquo are allundefined

A6 Bit-stringsVarious bit-string operation are defined over the type lsquobool listrsquo These are listed below

bit value middot ltmiddotgt bool listtimes nat rarr boolbit field middot ltmiddotmiddotgt bool listtimes nattimes nat rarr bool listconcatenation bool listtimes bool list rarr bool listduplication ^ bool listtimes nat rarr bool listaddition + bool listtimes bool list rarr bool listbitwise conjunction ampamp bool listtimes bool list rarr bool listbitwise disjunction || bool listtimes bool list rarr bool listbitwise exclusive-or bool listtimes bool list rarr bool listleft-shift ltlt bool listtimes nat rarr bool listright-shift gtgt+ bool listtimes nat rarr bool listrotate-right gtgt bool listtimes nat rarr bool list

The bit value operation gives the truth value of a bit-string at a given bit position for example

lsquo0s1101lt0gtrsquo = lsquotruersquo lsquo0s1101lt1gtrsquo = lsquofalsersquo lsquo0s1101lt2gtrsquo = lsquotruersquolsquo0s1101lt3gtrsquo = lsquotruersquo lsquo0s1101lt4gtrsquo = lsquofalsersquo lsquo0s1101lt5gtrsquo = lsquofalsersquo

25

The least-significant bit (position zero) occurs to the right of the bit-string The bit value oper-ation gives lsquofalsersquo when the bit position is greater than the size of the bit-string

The bit field operation extracts a range of bits from a bit-string For example

lsquo0s1101lt31gtrsquo = lsquo0s110rsquo and lsquo0s1101lt52gtrsquo = lsquo0s0011rsquo

In the bit-string expression xlthlgt the size of the result is always h + 1 minus l and the result isundefined when h lt l

Bit-string addition does not require the arguments to be of the same size and it gives anon-truncated result For example

lsquo0s101 + 0s1rsquo = lsquo0s110rsquo and lsquo0s101 + 0s11rsquo = lsquo0s1000rsquo

The operation ltlt performs a left-shift for example lsquo0s1101 ltlt 2rsquo = lsquo0s110100rsquo The oper-ation lsquorsquo is bit-string concatenation and lsquo^rsquo is duplication for example

lsquo0s101 0s11rsquo = lsquo0s10111rsquo and lsquo0s101 ^ 3rsquo = lsquo0s101101101rsquo

Regular list operations work as one would expect over bit-strings for example lsquoHead (0s101)rsquois a valid expression with value lsquotruersquo

A7 Characters and StringsThe following built-in functions are available for characters and strings

is alphabetic IsAlpha char rarr boolis alpha-numeric IsAlphaNum char rarr boolis decimal digit IsDigit char rarr boolis hexadecimal digit IsHexDigit char rarr boolis lowercase IsLower char rarr boolis uppercase IsUpper char rarr boolparse binary FromBinString string rarr num optionparse decimal FromDecString string rarr num optionparse hexadecimal FromHexString string rarr num optionconvert to lowercase ToLower string rarr stringconvert to uppercase ToUpper string rarr string

The following string operations are useful for parsing

split from the left splitl (char rarr bool) times string rarr string times stringsplit from the right splitr (char rarr bool) times string rarr string times stringsplit into fields fields (char rarr bool) times string rarr string listsplit into tokens tokens (char rarr bool) times string rarr string list

These are based on the SML functions Substringsplitl Substringsplitr Stringfieldsand Stringtokens Character predicates are declared using special syntax for example theexpression

splitl space or hexdigit and not in set a f ( 12bcab)

gives the result lsquo( 12bc ab)rsquo

26

A8 Floating-pointThe L3 language does not provide specialised types for representing floating-point numbersHowever 32-bit (single precision) and 64-bit (double precision) bit-vector values can be treatedas floating-point numbers the following IEEE compliant encoding formats are assumed

31 30 23 22 0

s e m1 8 23

63 62 52 51 0

s e m1 11 52

Here lsquosrsquo is the sign bit (set to lsquo1rsquo for negative numbers) lsquoersquo is a biased exponent value and lsquomrsquo is thesignificand The following constants and operations are available (where lsquofprsquo stands for bits(32)or bits(64) depending on the name of the operation)

rounding modes roundTiesToEvenroundTowardPositiveroundTowardNegativeroundTowardZero

ieee_rounding

flags (record) DivideByZero InvalidOpOverflow PrecisionUnderflow

ieee_flagsrarrbool

comparison values FP_LT FP_EQ FP_GT FP_UN ieee_compare

convert format FP32_ToFP64 fp32rarrfp64convert format FP64_ToFP32 ieee_roundingtimes fp64rarrfp32convert format FP64_ToFP32_ ieee_roundingtimes fp64rarr

ieee_flagstimes fp32from integer FP32|64_FromInt ieee_roundingtimes intrarrfpto integer FP32|64_ToInt ieee_roundingtimes fprarrint optionfrom string FP32|64 stringrarrfp

negative zero FP32|64_NegZero fppositive zero FP32|64_PosZero fpnegative infinity FP32|64_NegInf fppositive infinity FP32|64_PosInf fpa quiet NaN FP32|64_qNan fpa signalling NaN FP32|64_sNan fp

is integral FP32|64_IsIntegral fprarrboolis finite FP32|64_IsFinite fprarrboolis NaN FP32|64_IsNan fprarrboolis signalling NaN FP32|64_IsSignallingNan fprarrboolis normal FP32|64_IsNormal fprarrboolis sub-normal FP32|64_IsSubnormal fprarrboolis zero FP32|64_IsZero fprarrbool

27

comparison FP32|64_Compare fptimes fprarrieee_compareequality FP32|64_Equal fptimes fprarrboolless than FP32|64_LessThan fptimes fprarrboolless than or equal FP32|64_LessEqual fptimes fprarrboolgreater than FP32|64_GreaterThan fptimes fprarrboolgreater than or equal FP32|64_GreaterEqual fptimes fprarrbool

absolute FP32|64_Abs fprarrfpnegation FP32|64_Neg fprarrfpsquare root FP32|64_Sqrt ieee_roundingtimes fprarrfp(with flags) FP32|64_Sqrt_ ieee_roundingtimes fprarrieee_flagstimes fpaddition FP32|64_Add ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Add_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpsubtraction FP32|64_Sub ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Sub_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpmultiplication FP32|64_Mul ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Mul_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpfused multiply-add FP32|64_MulAdd ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulAdd_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpfused multiply-sub FP32|64_MulSub ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulSub_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpdivision FP32|64_Div ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Div_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fp

The L3 interpreter supports evaluation for 32-bit and 64-bit floating-point expressions but onlywhen running on an x86 machine that supports SSE2 extensions (Pentium 4 and later) Thefused multiply-addsub operations can only be interpreted on machines supporting the FMAextension which came in with the 4th generation (Haswell) Intel processors These restrictionsalso apply to any Standard ML code that is generated by L3

The IEEE 754 standard permits a number of different ways to flag underflow L3 predomi-nantly supports the x86 interpretation which detects underflow after rounding However whenexporting to HOL4 it is possible to choose detection before rounding which for example issuited to ARM instruction set models

A9 Miscellaneous operationsThe following operations are available

pair constructor αtimes β rarr αtimes βfirst of pair Fst αtimes β rarr αsecond of pair Snd αtimes β rarr β

casting [middot] α rarr βinitialise a map InitMap α rarr (βrarrα)

28

option constructor Some αrarrα optionoption projection ValOf α option rarr αoption test IsSome α option rarr bool

set membership in αtimesα set rarr boolset non-membership notin αtimesα set rarr boolset insertion insert αtimesα set rarrα setset union Union α settimesα set rarrα setset intersection Intersect α settimesα set rarrα setset difference Difference α settimesα set rarrα setset subset test IsSubset α settimesα set rarr boolset cardinality Cardinality α setrarr natset from a list SetOfList α list rarrα set

empty list Nil α listlist constructor Cons αtimesα list rarr α listlist head Head α list rarr αlist tail Tail α list rarr α listlist length Length α list rarr natlist concatenation α listtimesα list rarr α listlist flatten Concat α list list rarr α listlist element Element nattimesα list rarr αlist prefix Take nattimesα list rarr α listlist drop prefix Drop nattimesα list rarr α listlist pad left PadLeft αtimes nattimesα list rarr α listlist pad right PadRight αtimes nattimesα list rarr α listlist update Update αtimes nattimesα list rarr α listlist difference Remove α listtimesα list rarr α listlist intersection RemoveExcept α listtimesα list rarr α listlist without duplicates RemoveDuplicates α listrarr α listlist membership IsMember αtimesα list rarr boollist member position IndexOf αtimesα list rarr nat option

Sets are only defined over equality types see Appendix A2 The casting map is defined overcast-able types (as represented by the polymorphic type variables α and β) these are the primitivetypes (with the exception of lsquounitrsquo) and user defined enumerated types Assume lsquoEnumrsquo and lsquoEnum2rsquoare declared with

construct Enum One Two Three construct Enum2 Four Five Six Seven

The cast operations are described in Tables 1 to 7

29

Table 1 Cast to lsquoboolrsquo

From Operation Examples

bool identity lsquo[true]boolrsquo = lsquotruersquostring parse bool lsquo[true]boolrsquo = lsquotruersquo

lsquo[false]boolrsquo = lsquofalsersquootherwise undefined

nat is not zero lsquo[0n3]boolrsquo = lsquotruersquolsquo[0n0]boolrsquo = lsquofalsersquo

int is not zero lsquo[-0i1]boolrsquo = lsquotruersquolsquo[0i0]boolrsquo = lsquofalsersquo

bool list is not zero lsquo[0s11]boolrsquo = lsquotruersquolsquo[0s0]boolrsquo = lsquofalsersquo

bits(middot) is not zero lsquo[3`3]boolrsquo = lsquotruersquolsquo[0`3]boolrsquo = lsquofalsersquo

Enum is not the first element lsquo[One]boolrsquo = lsquofalsersquolsquo[Two]boolrsquo = lsquotruersquo

Table 2 Cast to lsquostringrsquo

From Operation Examples

bool name lsquo[true]stringrsquo = lsquotruersquostring identity lsquo[hello]stringrsquo = lsquohellorsquonat decimal lsquo[0n3]stringrsquo = lsquo3rsquoint signed decimal lsquo[-0i1]stringrsquo = lsquo~1rsquobool list binary lsquo[0s11]stringrsquo = lsquo11rsquobits(middot) unsigned hexadecimal lsquo[139`8]stringrsquo = lsquo8BrsquoEnum name lsquo[One]stringrsquo = lsquoOnersquo

30

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

and pretty-printing) In this case it is relatively easy for example to map between the MIPSinstruction syntax andi $5 $6 1024 and the expression lsquoANDI (5 6 1024)rsquo Defining anencoder in L3 is relatively straightforward for example

bits(32) Encode (iinstruction) =match i

middot middot middotcase ANDI (rs rt imm) =gt 001100 rs rt immmiddot middot middot

Such a function can be used to write a MIPS assembler which would map the assembly codesyntax andi $5 $6 1024 onto the machine-code value 0x30c50400

2 TutorialThis section gives a brief overview of how to install and use L3

Installation The sources for L3 can be downloaded from the following webpage

wwwclcamacuk~acjf3l3

The file l3tarbz2 can be unpacked with the command

$ tar xvjf l3tarbz2

This will create a directory of the form L3-YYYY-MM-DD where the year month and day willcorrespond with the release date The current version of L3 depends upon PolyML 57 whichcan be obtained from the site polymlorg If PolyML is installed then L3 can be built as follows

$ cd L3-YYYY-MM-DD$ make

Once built the following should appear when you start L315

$ l3ltlt L3 gtgtgt

Users should consider running L3 with the command rlwrap l316

15This assumes that the directory L3-YYYY-MM-DDbin has been added to the PATH environment variable16Details on rlwrap utility can be found at the site freecodecomprojectsrlwrap

16

Basic Interaction The command prompt for L3 is essentially the read-eval-print loop (REPL)of PolyML As such users are free to write arbitrary Standard ML code The structure Runtimeenables interaction with L3 The following shows an arithmetic evaluation in Standard ML aswell as in the L3 interpreter (evalQ)

gt 1 + 2val it = 3 intgt RuntimeevalQ `0i1 + 2`val it = `0i3` Termterm

Various error messages can occur when using the interpreter for example

gt RuntimeevalQ `1 + 2`Exception- Fail Could not infer all types raised

gt RuntimeevalQ `0i2 div 0`Exception- Except (Div SOME (div (int [`0i2` `0i0`]))) raised

The first error occurs because unannotated number literals are regarded as bit-vector values andhere the vector width cannot be inferred

L3 declarations can be made using the function loadQ The following sequence shows thedeclaration and manipulation of a global variable

gt RuntimeloadQ `declare n nat`ltVARgt nval it = () unit

gt RuntimeevalQ `n`val it = `UNKNOWNnat` Termterm

gt RuntimeevalQ ` n lt- 3 n `val it = `0n3` Termterm

The global state can be examined using the function show for example

gt Runtimeshow()val it = [(n `0n3`)] Evalterm_stack

The state can be ldquowipedrdquo clean using the function reset and all declarations can be wiped usinglsquoresetAllrsquo for example

gt Runtimereset()val it = () unitgt Runtimeshow()val it = [(n `UNKNOWNnat`)] Evalterm_stack

gt RuntimeresetAll()val it = () unitgt Runtimeshow()val it = [] Evalterm_stack

The function lsquoLoadQrsquo is similar to lsquoloadQrsquo but it performs a lsquoresetAllrsquo before making declarations

17

Constants The structure Consts provides various functions for working with L3 constantsMany of the operation in the Consts structure will be of little interest to end-users however itcan be used to display some helpful information

The function ConstslookupConst can be used to lookup an operation for example

gt ConstslookupConst Log2val it = Primitive [(bits(a) -gt bits(a) -) (nat -gt nat -)] const

Since lsquoLog2rsquo is a primitive operation only the valid types (ordered by overload priority) are showWith user operations the internal representation (definition) of the operation will be shownfor example

gt RuntimeLoadQ `unit demo () = ()`gt ConstslookupConst demoval it = Definition (Abs ([(_ (unit -))] unit -gt unit `()`) NONE 1)

Constsconst

The functions ConstslistDefinitions and ConstslistExceptions provide details of all useroperations and exceptions respectively The function lsquoConstsstatsrsquo gives a summary of all thecurrent declarations

gt Constsstats()Primitives 188Destructors 5Constructors 0Accessors 0Exceptions 0User operations 1Instruction definitions 0

Here the constructors for primitive types (such as lsquoConsrsquo) are counted under ldquoprimitivesrdquo

Types The Types structure can be used to display information relating to L3 types In partic-ular this structure provides the functions TypeslookupConst and TypeslistConsts which aredemonstrated below

gt RuntimeloadQ `construct enum One Two Three`gt TypeslistConsts()val it =

[(enumeq = true ast = false def = Constructors (Enum ltdict(3)gt) num = 0)]

(string typeconst) list

gt TypeslookupConst intval it = SOME eq = true ast = false def = BaseType num = ~1

typeconst option

18

Loading and Exporting Specifications When writing an L3 specification it is expected thatuser declarations will be contained in an L3 source file A sample instruction set specification(tinyspec) can be found in the L3 distribution subdirectory examples This specification isbased on Thackerrsquos pedagogical Tiny 3 architecture it can be loaded as follows

gt RuntimeLoadF tinyspecLoading tinyspecltTYPgt regTltTYPgt wordTmiddot middot middotltFUNgt test_progDone

The string argument to the functions RuntimeloadF and RuntimeLoadF can be in the form ofa comma separated list of files which will be loaded in order That is the call

RuntimeloadF aspec bspec

will load aspec followed by bspecThe function HolExportexport will export the current L3 specification in the form of an

HOL4 script for example

gt HolExportexport tinyraiseexception okfunction okmiddot middot middotmextend skipmunextend skipCreated file tinyScriptsmlCreated file tinyLibsmlCreated file tinyLibsigDone

The function HolExportspec provides a convenient shortcut for performing LoadF and exportusing just a single call for example HolExportspec (tinyspec tiny) will perform theload and export presented above

L3 is capable of exporting two styles of HOL specification an explicitly monadic version(based on state_transformerTheory) and a version that directly manipulates state using let-expressions (which is the default style) For example a monadic version of the Tiny specifi-cation can be exported using the command HolExportspec (tinyspec tiny monadic)Other export options include sigdocs nosigdocs (for setting HOLrsquos TheoryPPinclude_docstrace variable) bigrecords nobigrecords (for controlling HOLrsquos Datatypebig_record_size)and underflowbefore nounderflowbefore (for selecting the required IEEE 754 underflow be-haviour)

Generated HOL4 specifications are not designed to be manually edited (or human readable)To build an L3 specification script the HOL library Import is needed This library is currentlylocated in the directory $HOL_DIRexamplesl3-machine-codecommon and so adding this path tothe INCLUDES variable of a local Holmakefile is recommended The examplesl3-machine-codedirectory contains various examples of using L3 generated specifications

19

Testing Specifications Having written an L3 specification it is fairly easy to write code (inStandard ML) that runs test vectors Code for running the tinyspec example can be found inthe file run-tinyspec In this test harness the Tiny state is initialised and a small test programis loaded simply by evaluating the expression lsquoinitialize (test_prog)rsquo

It is also possible to evaluate (run) models that have been exported to HOL4 The filerun-tinysml shows how this can be accomplished for the Tiny example

20

A Primitive Types and OperationsThe primitive types are as follows

unit bool char nat int bits(middot) rounding

There are two infix type constructors lsquorsquo for pairs and lsquo-gtrsquo for maps There are also postfix typeconstructors lsquosetrsquo lsquooptionrsquo and lsquolistrsquo for example sets of strings are represented by the typelsquostring setrsquo The following sections describe these primitive types together with some detailsof associated operations The following constants and operations are available

nullary () Nil None false roundTiesToEven roundTowardNegativeroundTowardPositive roundTowardZero true

prefix - ~ Abs Cardinality Cons Difference Drop Element FP32_AbsFP32_Add FP32_Equal FP32_IsNan FP32_LessThan FP32_MulFP32_Neg FP32_Sub FP64_Abs FP64_Add FP64_Equal FP64_IsNanFP64_LessThan FP64_Mul FP64_Neg FP64_Sub FromBinStringFromDecString FromHexString Fst Head IndexOf InitMapIntersection IsAlpha IsAlphaNum IsDigit IsHexDigit IsLowerIsMember IsSome IsSubset IsUpper Length Log2 Max Min MsbQuotRem Remove RemoveDuplicates RemoveExcept ReverseSetOfList SignExtend SignedMax SignedMin Size Snd Some TailTake ToLower ToUpper Union Update ValOf ZeroExtend not

infix = ampamp + - lt lt+ lt= lt=+ ltgt == gt gt+ gt= gt=+ ^ || gtgtltlt gtgt+ ltlt gtgt and div in insert mod notin or quot rem

sdivsmodother middot ltmiddotgt middot ltmiddotmiddotgt [middot] fields splitl splitr tokens

Many arithmetic operations are overloaded Unless otherwise stated the order of selection islsquobits(middot)rsquo lsquonatrsquo lsquointrsquo and then lsquobool listrsquo

A1 UnitThe type lsquounitrsquo represents the singleton set containing the value lsquo()rsquo The primary use of thistype is as the return type for procedures

A2 BoolThe type lsquoboolrsquo represents the two element set B = lsquotruersquo lsquofalsersquo The following standardBoolean operations are available

negation not bool rarr boolconjunction and booltimes bool rarr booldisjunction or booltimes bool rarr boolequality == αtimesα rarr boolnon-equality ltgt = αtimesα rarr bool

21

The infix operators lsquoandrsquo and lsquoorrsquo are interpreted with short-circuit evaluation for example in theexpression lsquofalse and f()rsquo the value of lsquof()rsquo is not computed as the overall expression will alwaysevaluate to false This short-circuiting influences the side-effects that occur during expressionevaluation

There are two prefix symbols for logical negation (these are semantically identical) with lsquorsquobinding slightly tighter than lsquonotrsquo This distinction is becomes significant when working withequalities for example lsquonot a == brsquo is taken to be not(a = b) whereas lsquoa == brsquo is (nota) = b

Equality is only defined with respect to equality types represented here by the type variableα An equality type is any type built without the used of the map operator lsquo-gtrsquo

A3 NatThe type lsquonatrsquo represents the natural numbers N = 0 1 2 The following operations areavailable

logarithm (base two) Log2 nat rarr natminimum value Min nattimes nat rarr natmaximium value Max nattimes nat rarr natless than lt nattimes nat rarr boolgreater than gt nattimes nat rarr boolless than or equal to lt= nattimes nat rarr boolgreater than or equal to gt= nattimes nat rarr booladdition + nattimes nat rarr natsubtraction - nattimes nat rarr natmultiplication nattimes nat rarr natexponentiation nattimes nat rarr natdivision div nattimes nat rarr natmodulus mod nattimes nat rarr nat

The lsquodivrsquo and lsquomodrsquo operations satisfy the following property

foralln 0 lt n =rArr forallk k = (k div n) lowast n+ (k mod n) and (k mod n) lt n

The expressions lsquoLog2(0)rsquo lsquox div 0rsquo and lsquox mod 0rsquo are all undefined 17

A4 IntThe type lsquointrsquo represents the integers Z = Ncupminus1minus2minus3 The following operations areavailable

17The interpreter will raise an exception when attempting to evaluate them

22

unary minus - int rarr intabsolute value Abs int rarr intminimum value Min inttimes int rarr intmaximum value Max inttimes int rarr intless than lt inttimes int rarr boolgreater than gt inttimes int rarr boolless than or equal to lt= inttimes int rarr boolgreater than or equal to gt= inttimes int rarr booladdition + inttimes int rarr intsubtraction - inttimes int rarr intmultiplication inttimes int rarr intexponentiation inttimes nat rarr intquotient and remainder QuotRem inttimes int rarr inttimes intquotient quot inttimes int rarr intremainder rem inttimes int rarr intdivision div inttimes int rarr intmodulus mod inttimes int rarr int

The operation lsquoAbsrsquo gives an positive integer value for example lsquoAbs(-2)rsquo = lsquo2rsquo The integeroperations lsquoquotrsquo and lsquodivrsquo are related to natural number division as follows

i quot j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

and

i div j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(minusi) div n(j))minus 1 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i and n(i) mod n(minusj) = 0

minus z(n(i) div n(minusj))minus 1 j lt 0 and 0 le i and n(i) mod n(minusj) = 0

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

where z NrarrZ and n ZrarrN are value preserving maps The lsquoremrsquo and lsquomodrsquo operations satisfythe equations

i rem j =

iminus (i quot j) lowast j j = 0

undefined j = 0i mod j =

iminus (i div j) lowast j j = 0

undefined j = 0

A5 Bit-vectorsThe type lsquobits(n)rsquo represents fixed-width (n-bit) words also known as bit-vectors for examplebits(32) is the type of 32-bit machine words18 The bits type can be viewed as representing

18These are called double-words (dword) in the x86 architecture and simply words in the ARM architecture

23

the set Zn = 0 1 2nminus1 for some 0 lt n At the type system level no distinction is madebetween signed and unsigned words however some operations (such as orderings) have signedand unsigned variants

The following bit-vector operations are available

1rsquos complement ~ bits(n) rarr bits(n)2rsquos complement - bits(n) rarr bits(n)absolute value Abs bits(n) rarr bits(n)logarithm (base two) Log2 bits(n) rarr bits(n)zero-extend ZeroExtend bits(m) rarr bits(n)sign-extend SignExtend bits(m) rarr bits(n)reverse bits Reverse bits(n) rarr bits(n)minimum value (u) Min bits(n)times bits(n) rarr bits(n)maximum value (u) Max bits(n)times bits(n) rarr bits(n)minimum value (s) SignedMin bits(n)times bits(n) rarr bits(n)maximum value (s) SignedMax bits(n)times bits(n) rarr bits(n)widthsize Size bits(n) rarr natmost-significant (sign) bit Msb bits(n) rarr boolbit value middot ltmiddotgt bits(n)times nat rarr boolbit field middot ltmiddotmiddotgt bits(m)times nattimes nat rarr bits(n)concatenation bits(m)times bits(n) rarr bits(p)duplication ^ bits(m)times nat rarr bits(n)less than (s) lt bits(n)times bits(n) rarr boolgreater than (s) gt bits(n)times bits(n) rarr boolless than or equal to (s) lt= bits(n)times bits(n) rarr boolgreater than or equal to (s) gt= bits(n)times bits(n) rarr boolless than (u) lt+ bits(n)times bits(n) rarr boolgreater than (u) gt+ bits(n)times bits(n) rarr boolless than or equal to (u) lt=+ bits(n)times bits(n) rarr boolgreater than or equal to (u) gt=+ bits(n)times bits(n) rarr booladdition + bits(n)times bits(n) rarr bits(n)subtraction - bits(n)times bits(n) rarr bits(n)multiplication bits(n)times bits(n) rarr bits(n)quotient (s) quot bits(n)times bits(n) rarr bits(n)remained (s) rem bits(n)times bits(n) rarr bits(n)division (u) div bits(n)times bits(n) rarr bits(n)modulus (u) mod bits(n)times bits(n) rarr bits(n)division (s) sdiv bits(n)times bits(n) rarr bits(n)modulus (s) smod bits(n)times bits(n) rarr bits(n)bitwise conjunction ampamp bits(n)times bits(n) rarr bits(n)bitwise disjunction || bits(n)times bits(n) rarr bits(n)bitwise exclusive-or bits(n)times bits(n) rarr bits(n)

Unsigned operations are labelled with (u) and signed operations are labelled with (s)The shift operations support shifting by either a bit-vector value or by a natural number value

The overloading is resolved such that the lsquonatrsquo variant is selected over the lsquobits(middot)rsquo version Theshift operations are

24

left-shift ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (u) gtgt+ bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (s) gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate left ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate right gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

A number of operations are undefined depending on the types of their domain and rangeThis is detailed in the following table

Operation Undefined when

ZeroExtend(x`n)`m m lt nSignExtend(x`n)`m m lt n(x`m)ltpgt m le p(x`m)lthlgt`n n = h+ 1minus l or h lt l orm le h((xm) (yn))`p p = m+ n((x`m) ^ n)`p p = m middot n (which covers n = 0)

The type checker will fail when these conditions are obviously violated Alternatively the inter-preter may raise a runtime error when these conditions are not met

As before the expressions lsquoLog2(0)rsquo lsquox quot 0rsquo lsquox rem 0rsquo lsquox div 0rsquo and lsquox mod 0rsquo are allundefined

A6 Bit-stringsVarious bit-string operation are defined over the type lsquobool listrsquo These are listed below

bit value middot ltmiddotgt bool listtimes nat rarr boolbit field middot ltmiddotmiddotgt bool listtimes nattimes nat rarr bool listconcatenation bool listtimes bool list rarr bool listduplication ^ bool listtimes nat rarr bool listaddition + bool listtimes bool list rarr bool listbitwise conjunction ampamp bool listtimes bool list rarr bool listbitwise disjunction || bool listtimes bool list rarr bool listbitwise exclusive-or bool listtimes bool list rarr bool listleft-shift ltlt bool listtimes nat rarr bool listright-shift gtgt+ bool listtimes nat rarr bool listrotate-right gtgt bool listtimes nat rarr bool list

The bit value operation gives the truth value of a bit-string at a given bit position for example

lsquo0s1101lt0gtrsquo = lsquotruersquo lsquo0s1101lt1gtrsquo = lsquofalsersquo lsquo0s1101lt2gtrsquo = lsquotruersquolsquo0s1101lt3gtrsquo = lsquotruersquo lsquo0s1101lt4gtrsquo = lsquofalsersquo lsquo0s1101lt5gtrsquo = lsquofalsersquo

25

The least-significant bit (position zero) occurs to the right of the bit-string The bit value oper-ation gives lsquofalsersquo when the bit position is greater than the size of the bit-string

The bit field operation extracts a range of bits from a bit-string For example

lsquo0s1101lt31gtrsquo = lsquo0s110rsquo and lsquo0s1101lt52gtrsquo = lsquo0s0011rsquo

In the bit-string expression xlthlgt the size of the result is always h + 1 minus l and the result isundefined when h lt l

Bit-string addition does not require the arguments to be of the same size and it gives anon-truncated result For example

lsquo0s101 + 0s1rsquo = lsquo0s110rsquo and lsquo0s101 + 0s11rsquo = lsquo0s1000rsquo

The operation ltlt performs a left-shift for example lsquo0s1101 ltlt 2rsquo = lsquo0s110100rsquo The oper-ation lsquorsquo is bit-string concatenation and lsquo^rsquo is duplication for example

lsquo0s101 0s11rsquo = lsquo0s10111rsquo and lsquo0s101 ^ 3rsquo = lsquo0s101101101rsquo

Regular list operations work as one would expect over bit-strings for example lsquoHead (0s101)rsquois a valid expression with value lsquotruersquo

A7 Characters and StringsThe following built-in functions are available for characters and strings

is alphabetic IsAlpha char rarr boolis alpha-numeric IsAlphaNum char rarr boolis decimal digit IsDigit char rarr boolis hexadecimal digit IsHexDigit char rarr boolis lowercase IsLower char rarr boolis uppercase IsUpper char rarr boolparse binary FromBinString string rarr num optionparse decimal FromDecString string rarr num optionparse hexadecimal FromHexString string rarr num optionconvert to lowercase ToLower string rarr stringconvert to uppercase ToUpper string rarr string

The following string operations are useful for parsing

split from the left splitl (char rarr bool) times string rarr string times stringsplit from the right splitr (char rarr bool) times string rarr string times stringsplit into fields fields (char rarr bool) times string rarr string listsplit into tokens tokens (char rarr bool) times string rarr string list

These are based on the SML functions Substringsplitl Substringsplitr Stringfieldsand Stringtokens Character predicates are declared using special syntax for example theexpression

splitl space or hexdigit and not in set a f ( 12bcab)

gives the result lsquo( 12bc ab)rsquo

26

A8 Floating-pointThe L3 language does not provide specialised types for representing floating-point numbersHowever 32-bit (single precision) and 64-bit (double precision) bit-vector values can be treatedas floating-point numbers the following IEEE compliant encoding formats are assumed

31 30 23 22 0

s e m1 8 23

63 62 52 51 0

s e m1 11 52

Here lsquosrsquo is the sign bit (set to lsquo1rsquo for negative numbers) lsquoersquo is a biased exponent value and lsquomrsquo is thesignificand The following constants and operations are available (where lsquofprsquo stands for bits(32)or bits(64) depending on the name of the operation)

rounding modes roundTiesToEvenroundTowardPositiveroundTowardNegativeroundTowardZero

ieee_rounding

flags (record) DivideByZero InvalidOpOverflow PrecisionUnderflow

ieee_flagsrarrbool

comparison values FP_LT FP_EQ FP_GT FP_UN ieee_compare

convert format FP32_ToFP64 fp32rarrfp64convert format FP64_ToFP32 ieee_roundingtimes fp64rarrfp32convert format FP64_ToFP32_ ieee_roundingtimes fp64rarr

ieee_flagstimes fp32from integer FP32|64_FromInt ieee_roundingtimes intrarrfpto integer FP32|64_ToInt ieee_roundingtimes fprarrint optionfrom string FP32|64 stringrarrfp

negative zero FP32|64_NegZero fppositive zero FP32|64_PosZero fpnegative infinity FP32|64_NegInf fppositive infinity FP32|64_PosInf fpa quiet NaN FP32|64_qNan fpa signalling NaN FP32|64_sNan fp

is integral FP32|64_IsIntegral fprarrboolis finite FP32|64_IsFinite fprarrboolis NaN FP32|64_IsNan fprarrboolis signalling NaN FP32|64_IsSignallingNan fprarrboolis normal FP32|64_IsNormal fprarrboolis sub-normal FP32|64_IsSubnormal fprarrboolis zero FP32|64_IsZero fprarrbool

27

comparison FP32|64_Compare fptimes fprarrieee_compareequality FP32|64_Equal fptimes fprarrboolless than FP32|64_LessThan fptimes fprarrboolless than or equal FP32|64_LessEqual fptimes fprarrboolgreater than FP32|64_GreaterThan fptimes fprarrboolgreater than or equal FP32|64_GreaterEqual fptimes fprarrbool

absolute FP32|64_Abs fprarrfpnegation FP32|64_Neg fprarrfpsquare root FP32|64_Sqrt ieee_roundingtimes fprarrfp(with flags) FP32|64_Sqrt_ ieee_roundingtimes fprarrieee_flagstimes fpaddition FP32|64_Add ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Add_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpsubtraction FP32|64_Sub ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Sub_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpmultiplication FP32|64_Mul ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Mul_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpfused multiply-add FP32|64_MulAdd ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulAdd_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpfused multiply-sub FP32|64_MulSub ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulSub_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpdivision FP32|64_Div ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Div_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fp

The L3 interpreter supports evaluation for 32-bit and 64-bit floating-point expressions but onlywhen running on an x86 machine that supports SSE2 extensions (Pentium 4 and later) Thefused multiply-addsub operations can only be interpreted on machines supporting the FMAextension which came in with the 4th generation (Haswell) Intel processors These restrictionsalso apply to any Standard ML code that is generated by L3

The IEEE 754 standard permits a number of different ways to flag underflow L3 predomi-nantly supports the x86 interpretation which detects underflow after rounding However whenexporting to HOL4 it is possible to choose detection before rounding which for example issuited to ARM instruction set models

A9 Miscellaneous operationsThe following operations are available

pair constructor αtimes β rarr αtimes βfirst of pair Fst αtimes β rarr αsecond of pair Snd αtimes β rarr β

casting [middot] α rarr βinitialise a map InitMap α rarr (βrarrα)

28

option constructor Some αrarrα optionoption projection ValOf α option rarr αoption test IsSome α option rarr bool

set membership in αtimesα set rarr boolset non-membership notin αtimesα set rarr boolset insertion insert αtimesα set rarrα setset union Union α settimesα set rarrα setset intersection Intersect α settimesα set rarrα setset difference Difference α settimesα set rarrα setset subset test IsSubset α settimesα set rarr boolset cardinality Cardinality α setrarr natset from a list SetOfList α list rarrα set

empty list Nil α listlist constructor Cons αtimesα list rarr α listlist head Head α list rarr αlist tail Tail α list rarr α listlist length Length α list rarr natlist concatenation α listtimesα list rarr α listlist flatten Concat α list list rarr α listlist element Element nattimesα list rarr αlist prefix Take nattimesα list rarr α listlist drop prefix Drop nattimesα list rarr α listlist pad left PadLeft αtimes nattimesα list rarr α listlist pad right PadRight αtimes nattimesα list rarr α listlist update Update αtimes nattimesα list rarr α listlist difference Remove α listtimesα list rarr α listlist intersection RemoveExcept α listtimesα list rarr α listlist without duplicates RemoveDuplicates α listrarr α listlist membership IsMember αtimesα list rarr boollist member position IndexOf αtimesα list rarr nat option

Sets are only defined over equality types see Appendix A2 The casting map is defined overcast-able types (as represented by the polymorphic type variables α and β) these are the primitivetypes (with the exception of lsquounitrsquo) and user defined enumerated types Assume lsquoEnumrsquo and lsquoEnum2rsquoare declared with

construct Enum One Two Three construct Enum2 Four Five Six Seven

The cast operations are described in Tables 1 to 7

29

Table 1 Cast to lsquoboolrsquo

From Operation Examples

bool identity lsquo[true]boolrsquo = lsquotruersquostring parse bool lsquo[true]boolrsquo = lsquotruersquo

lsquo[false]boolrsquo = lsquofalsersquootherwise undefined

nat is not zero lsquo[0n3]boolrsquo = lsquotruersquolsquo[0n0]boolrsquo = lsquofalsersquo

int is not zero lsquo[-0i1]boolrsquo = lsquotruersquolsquo[0i0]boolrsquo = lsquofalsersquo

bool list is not zero lsquo[0s11]boolrsquo = lsquotruersquolsquo[0s0]boolrsquo = lsquofalsersquo

bits(middot) is not zero lsquo[3`3]boolrsquo = lsquotruersquolsquo[0`3]boolrsquo = lsquofalsersquo

Enum is not the first element lsquo[One]boolrsquo = lsquofalsersquolsquo[Two]boolrsquo = lsquotruersquo

Table 2 Cast to lsquostringrsquo

From Operation Examples

bool name lsquo[true]stringrsquo = lsquotruersquostring identity lsquo[hello]stringrsquo = lsquohellorsquonat decimal lsquo[0n3]stringrsquo = lsquo3rsquoint signed decimal lsquo[-0i1]stringrsquo = lsquo~1rsquobool list binary lsquo[0s11]stringrsquo = lsquo11rsquobits(middot) unsigned hexadecimal lsquo[139`8]stringrsquo = lsquo8BrsquoEnum name lsquo[One]stringrsquo = lsquoOnersquo

30

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

Basic Interaction The command prompt for L3 is essentially the read-eval-print loop (REPL)of PolyML As such users are free to write arbitrary Standard ML code The structure Runtimeenables interaction with L3 The following shows an arithmetic evaluation in Standard ML aswell as in the L3 interpreter (evalQ)

gt 1 + 2val it = 3 intgt RuntimeevalQ `0i1 + 2`val it = `0i3` Termterm

Various error messages can occur when using the interpreter for example

gt RuntimeevalQ `1 + 2`Exception- Fail Could not infer all types raised

gt RuntimeevalQ `0i2 div 0`Exception- Except (Div SOME (div (int [`0i2` `0i0`]))) raised

The first error occurs because unannotated number literals are regarded as bit-vector values andhere the vector width cannot be inferred

L3 declarations can be made using the function loadQ The following sequence shows thedeclaration and manipulation of a global variable

gt RuntimeloadQ `declare n nat`ltVARgt nval it = () unit

gt RuntimeevalQ `n`val it = `UNKNOWNnat` Termterm

gt RuntimeevalQ ` n lt- 3 n `val it = `0n3` Termterm

The global state can be examined using the function show for example

gt Runtimeshow()val it = [(n `0n3`)] Evalterm_stack

The state can be ldquowipedrdquo clean using the function reset and all declarations can be wiped usinglsquoresetAllrsquo for example

gt Runtimereset()val it = () unitgt Runtimeshow()val it = [(n `UNKNOWNnat`)] Evalterm_stack

gt RuntimeresetAll()val it = () unitgt Runtimeshow()val it = [] Evalterm_stack

The function lsquoLoadQrsquo is similar to lsquoloadQrsquo but it performs a lsquoresetAllrsquo before making declarations

17

Constants The structure Consts provides various functions for working with L3 constantsMany of the operation in the Consts structure will be of little interest to end-users however itcan be used to display some helpful information

The function ConstslookupConst can be used to lookup an operation for example

gt ConstslookupConst Log2val it = Primitive [(bits(a) -gt bits(a) -) (nat -gt nat -)] const

Since lsquoLog2rsquo is a primitive operation only the valid types (ordered by overload priority) are showWith user operations the internal representation (definition) of the operation will be shownfor example

gt RuntimeLoadQ `unit demo () = ()`gt ConstslookupConst demoval it = Definition (Abs ([(_ (unit -))] unit -gt unit `()`) NONE 1)

Constsconst

The functions ConstslistDefinitions and ConstslistExceptions provide details of all useroperations and exceptions respectively The function lsquoConstsstatsrsquo gives a summary of all thecurrent declarations

gt Constsstats()Primitives 188Destructors 5Constructors 0Accessors 0Exceptions 0User operations 1Instruction definitions 0

Here the constructors for primitive types (such as lsquoConsrsquo) are counted under ldquoprimitivesrdquo

Types The Types structure can be used to display information relating to L3 types In partic-ular this structure provides the functions TypeslookupConst and TypeslistConsts which aredemonstrated below

gt RuntimeloadQ `construct enum One Two Three`gt TypeslistConsts()val it =

[(enumeq = true ast = false def = Constructors (Enum ltdict(3)gt) num = 0)]

(string typeconst) list

gt TypeslookupConst intval it = SOME eq = true ast = false def = BaseType num = ~1

typeconst option

18

Loading and Exporting Specifications When writing an L3 specification it is expected thatuser declarations will be contained in an L3 source file A sample instruction set specification(tinyspec) can be found in the L3 distribution subdirectory examples This specification isbased on Thackerrsquos pedagogical Tiny 3 architecture it can be loaded as follows

gt RuntimeLoadF tinyspecLoading tinyspecltTYPgt regTltTYPgt wordTmiddot middot middotltFUNgt test_progDone

The string argument to the functions RuntimeloadF and RuntimeLoadF can be in the form ofa comma separated list of files which will be loaded in order That is the call

RuntimeloadF aspec bspec

will load aspec followed by bspecThe function HolExportexport will export the current L3 specification in the form of an

HOL4 script for example

gt HolExportexport tinyraiseexception okfunction okmiddot middot middotmextend skipmunextend skipCreated file tinyScriptsmlCreated file tinyLibsmlCreated file tinyLibsigDone

The function HolExportspec provides a convenient shortcut for performing LoadF and exportusing just a single call for example HolExportspec (tinyspec tiny) will perform theload and export presented above

L3 is capable of exporting two styles of HOL specification an explicitly monadic version(based on state_transformerTheory) and a version that directly manipulates state using let-expressions (which is the default style) For example a monadic version of the Tiny specifi-cation can be exported using the command HolExportspec (tinyspec tiny monadic)Other export options include sigdocs nosigdocs (for setting HOLrsquos TheoryPPinclude_docstrace variable) bigrecords nobigrecords (for controlling HOLrsquos Datatypebig_record_size)and underflowbefore nounderflowbefore (for selecting the required IEEE 754 underflow be-haviour)

Generated HOL4 specifications are not designed to be manually edited (or human readable)To build an L3 specification script the HOL library Import is needed This library is currentlylocated in the directory $HOL_DIRexamplesl3-machine-codecommon and so adding this path tothe INCLUDES variable of a local Holmakefile is recommended The examplesl3-machine-codedirectory contains various examples of using L3 generated specifications

19

Testing Specifications Having written an L3 specification it is fairly easy to write code (inStandard ML) that runs test vectors Code for running the tinyspec example can be found inthe file run-tinyspec In this test harness the Tiny state is initialised and a small test programis loaded simply by evaluating the expression lsquoinitialize (test_prog)rsquo

It is also possible to evaluate (run) models that have been exported to HOL4 The filerun-tinysml shows how this can be accomplished for the Tiny example

20

A Primitive Types and OperationsThe primitive types are as follows

unit bool char nat int bits(middot) rounding

There are two infix type constructors lsquorsquo for pairs and lsquo-gtrsquo for maps There are also postfix typeconstructors lsquosetrsquo lsquooptionrsquo and lsquolistrsquo for example sets of strings are represented by the typelsquostring setrsquo The following sections describe these primitive types together with some detailsof associated operations The following constants and operations are available

nullary () Nil None false roundTiesToEven roundTowardNegativeroundTowardPositive roundTowardZero true

prefix - ~ Abs Cardinality Cons Difference Drop Element FP32_AbsFP32_Add FP32_Equal FP32_IsNan FP32_LessThan FP32_MulFP32_Neg FP32_Sub FP64_Abs FP64_Add FP64_Equal FP64_IsNanFP64_LessThan FP64_Mul FP64_Neg FP64_Sub FromBinStringFromDecString FromHexString Fst Head IndexOf InitMapIntersection IsAlpha IsAlphaNum IsDigit IsHexDigit IsLowerIsMember IsSome IsSubset IsUpper Length Log2 Max Min MsbQuotRem Remove RemoveDuplicates RemoveExcept ReverseSetOfList SignExtend SignedMax SignedMin Size Snd Some TailTake ToLower ToUpper Union Update ValOf ZeroExtend not

infix = ampamp + - lt lt+ lt= lt=+ ltgt == gt gt+ gt= gt=+ ^ || gtgtltlt gtgt+ ltlt gtgt and div in insert mod notin or quot rem

sdivsmodother middot ltmiddotgt middot ltmiddotmiddotgt [middot] fields splitl splitr tokens

Many arithmetic operations are overloaded Unless otherwise stated the order of selection islsquobits(middot)rsquo lsquonatrsquo lsquointrsquo and then lsquobool listrsquo

A1 UnitThe type lsquounitrsquo represents the singleton set containing the value lsquo()rsquo The primary use of thistype is as the return type for procedures

A2 BoolThe type lsquoboolrsquo represents the two element set B = lsquotruersquo lsquofalsersquo The following standardBoolean operations are available

negation not bool rarr boolconjunction and booltimes bool rarr booldisjunction or booltimes bool rarr boolequality == αtimesα rarr boolnon-equality ltgt = αtimesα rarr bool

21

The infix operators lsquoandrsquo and lsquoorrsquo are interpreted with short-circuit evaluation for example in theexpression lsquofalse and f()rsquo the value of lsquof()rsquo is not computed as the overall expression will alwaysevaluate to false This short-circuiting influences the side-effects that occur during expressionevaluation

There are two prefix symbols for logical negation (these are semantically identical) with lsquorsquobinding slightly tighter than lsquonotrsquo This distinction is becomes significant when working withequalities for example lsquonot a == brsquo is taken to be not(a = b) whereas lsquoa == brsquo is (nota) = b

Equality is only defined with respect to equality types represented here by the type variableα An equality type is any type built without the used of the map operator lsquo-gtrsquo

A3 NatThe type lsquonatrsquo represents the natural numbers N = 0 1 2 The following operations areavailable

logarithm (base two) Log2 nat rarr natminimum value Min nattimes nat rarr natmaximium value Max nattimes nat rarr natless than lt nattimes nat rarr boolgreater than gt nattimes nat rarr boolless than or equal to lt= nattimes nat rarr boolgreater than or equal to gt= nattimes nat rarr booladdition + nattimes nat rarr natsubtraction - nattimes nat rarr natmultiplication nattimes nat rarr natexponentiation nattimes nat rarr natdivision div nattimes nat rarr natmodulus mod nattimes nat rarr nat

The lsquodivrsquo and lsquomodrsquo operations satisfy the following property

foralln 0 lt n =rArr forallk k = (k div n) lowast n+ (k mod n) and (k mod n) lt n

The expressions lsquoLog2(0)rsquo lsquox div 0rsquo and lsquox mod 0rsquo are all undefined 17

A4 IntThe type lsquointrsquo represents the integers Z = Ncupminus1minus2minus3 The following operations areavailable

17The interpreter will raise an exception when attempting to evaluate them

22

unary minus - int rarr intabsolute value Abs int rarr intminimum value Min inttimes int rarr intmaximum value Max inttimes int rarr intless than lt inttimes int rarr boolgreater than gt inttimes int rarr boolless than or equal to lt= inttimes int rarr boolgreater than or equal to gt= inttimes int rarr booladdition + inttimes int rarr intsubtraction - inttimes int rarr intmultiplication inttimes int rarr intexponentiation inttimes nat rarr intquotient and remainder QuotRem inttimes int rarr inttimes intquotient quot inttimes int rarr intremainder rem inttimes int rarr intdivision div inttimes int rarr intmodulus mod inttimes int rarr int

The operation lsquoAbsrsquo gives an positive integer value for example lsquoAbs(-2)rsquo = lsquo2rsquo The integeroperations lsquoquotrsquo and lsquodivrsquo are related to natural number division as follows

i quot j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

and

i div j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(minusi) div n(j))minus 1 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i and n(i) mod n(minusj) = 0

minus z(n(i) div n(minusj))minus 1 j lt 0 and 0 le i and n(i) mod n(minusj) = 0

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

where z NrarrZ and n ZrarrN are value preserving maps The lsquoremrsquo and lsquomodrsquo operations satisfythe equations

i rem j =

iminus (i quot j) lowast j j = 0

undefined j = 0i mod j =

iminus (i div j) lowast j j = 0

undefined j = 0

A5 Bit-vectorsThe type lsquobits(n)rsquo represents fixed-width (n-bit) words also known as bit-vectors for examplebits(32) is the type of 32-bit machine words18 The bits type can be viewed as representing

18These are called double-words (dword) in the x86 architecture and simply words in the ARM architecture

23

the set Zn = 0 1 2nminus1 for some 0 lt n At the type system level no distinction is madebetween signed and unsigned words however some operations (such as orderings) have signedand unsigned variants

The following bit-vector operations are available

1rsquos complement ~ bits(n) rarr bits(n)2rsquos complement - bits(n) rarr bits(n)absolute value Abs bits(n) rarr bits(n)logarithm (base two) Log2 bits(n) rarr bits(n)zero-extend ZeroExtend bits(m) rarr bits(n)sign-extend SignExtend bits(m) rarr bits(n)reverse bits Reverse bits(n) rarr bits(n)minimum value (u) Min bits(n)times bits(n) rarr bits(n)maximum value (u) Max bits(n)times bits(n) rarr bits(n)minimum value (s) SignedMin bits(n)times bits(n) rarr bits(n)maximum value (s) SignedMax bits(n)times bits(n) rarr bits(n)widthsize Size bits(n) rarr natmost-significant (sign) bit Msb bits(n) rarr boolbit value middot ltmiddotgt bits(n)times nat rarr boolbit field middot ltmiddotmiddotgt bits(m)times nattimes nat rarr bits(n)concatenation bits(m)times bits(n) rarr bits(p)duplication ^ bits(m)times nat rarr bits(n)less than (s) lt bits(n)times bits(n) rarr boolgreater than (s) gt bits(n)times bits(n) rarr boolless than or equal to (s) lt= bits(n)times bits(n) rarr boolgreater than or equal to (s) gt= bits(n)times bits(n) rarr boolless than (u) lt+ bits(n)times bits(n) rarr boolgreater than (u) gt+ bits(n)times bits(n) rarr boolless than or equal to (u) lt=+ bits(n)times bits(n) rarr boolgreater than or equal to (u) gt=+ bits(n)times bits(n) rarr booladdition + bits(n)times bits(n) rarr bits(n)subtraction - bits(n)times bits(n) rarr bits(n)multiplication bits(n)times bits(n) rarr bits(n)quotient (s) quot bits(n)times bits(n) rarr bits(n)remained (s) rem bits(n)times bits(n) rarr bits(n)division (u) div bits(n)times bits(n) rarr bits(n)modulus (u) mod bits(n)times bits(n) rarr bits(n)division (s) sdiv bits(n)times bits(n) rarr bits(n)modulus (s) smod bits(n)times bits(n) rarr bits(n)bitwise conjunction ampamp bits(n)times bits(n) rarr bits(n)bitwise disjunction || bits(n)times bits(n) rarr bits(n)bitwise exclusive-or bits(n)times bits(n) rarr bits(n)

Unsigned operations are labelled with (u) and signed operations are labelled with (s)The shift operations support shifting by either a bit-vector value or by a natural number value

The overloading is resolved such that the lsquonatrsquo variant is selected over the lsquobits(middot)rsquo version Theshift operations are

24

left-shift ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (u) gtgt+ bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (s) gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate left ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate right gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

A number of operations are undefined depending on the types of their domain and rangeThis is detailed in the following table

Operation Undefined when

ZeroExtend(x`n)`m m lt nSignExtend(x`n)`m m lt n(x`m)ltpgt m le p(x`m)lthlgt`n n = h+ 1minus l or h lt l orm le h((xm) (yn))`p p = m+ n((x`m) ^ n)`p p = m middot n (which covers n = 0)

The type checker will fail when these conditions are obviously violated Alternatively the inter-preter may raise a runtime error when these conditions are not met

As before the expressions lsquoLog2(0)rsquo lsquox quot 0rsquo lsquox rem 0rsquo lsquox div 0rsquo and lsquox mod 0rsquo are allundefined

A6 Bit-stringsVarious bit-string operation are defined over the type lsquobool listrsquo These are listed below

bit value middot ltmiddotgt bool listtimes nat rarr boolbit field middot ltmiddotmiddotgt bool listtimes nattimes nat rarr bool listconcatenation bool listtimes bool list rarr bool listduplication ^ bool listtimes nat rarr bool listaddition + bool listtimes bool list rarr bool listbitwise conjunction ampamp bool listtimes bool list rarr bool listbitwise disjunction || bool listtimes bool list rarr bool listbitwise exclusive-or bool listtimes bool list rarr bool listleft-shift ltlt bool listtimes nat rarr bool listright-shift gtgt+ bool listtimes nat rarr bool listrotate-right gtgt bool listtimes nat rarr bool list

The bit value operation gives the truth value of a bit-string at a given bit position for example

lsquo0s1101lt0gtrsquo = lsquotruersquo lsquo0s1101lt1gtrsquo = lsquofalsersquo lsquo0s1101lt2gtrsquo = lsquotruersquolsquo0s1101lt3gtrsquo = lsquotruersquo lsquo0s1101lt4gtrsquo = lsquofalsersquo lsquo0s1101lt5gtrsquo = lsquofalsersquo

25

The least-significant bit (position zero) occurs to the right of the bit-string The bit value oper-ation gives lsquofalsersquo when the bit position is greater than the size of the bit-string

The bit field operation extracts a range of bits from a bit-string For example

lsquo0s1101lt31gtrsquo = lsquo0s110rsquo and lsquo0s1101lt52gtrsquo = lsquo0s0011rsquo

In the bit-string expression xlthlgt the size of the result is always h + 1 minus l and the result isundefined when h lt l

Bit-string addition does not require the arguments to be of the same size and it gives anon-truncated result For example

lsquo0s101 + 0s1rsquo = lsquo0s110rsquo and lsquo0s101 + 0s11rsquo = lsquo0s1000rsquo

The operation ltlt performs a left-shift for example lsquo0s1101 ltlt 2rsquo = lsquo0s110100rsquo The oper-ation lsquorsquo is bit-string concatenation and lsquo^rsquo is duplication for example

lsquo0s101 0s11rsquo = lsquo0s10111rsquo and lsquo0s101 ^ 3rsquo = lsquo0s101101101rsquo

Regular list operations work as one would expect over bit-strings for example lsquoHead (0s101)rsquois a valid expression with value lsquotruersquo

A7 Characters and StringsThe following built-in functions are available for characters and strings

is alphabetic IsAlpha char rarr boolis alpha-numeric IsAlphaNum char rarr boolis decimal digit IsDigit char rarr boolis hexadecimal digit IsHexDigit char rarr boolis lowercase IsLower char rarr boolis uppercase IsUpper char rarr boolparse binary FromBinString string rarr num optionparse decimal FromDecString string rarr num optionparse hexadecimal FromHexString string rarr num optionconvert to lowercase ToLower string rarr stringconvert to uppercase ToUpper string rarr string

The following string operations are useful for parsing

split from the left splitl (char rarr bool) times string rarr string times stringsplit from the right splitr (char rarr bool) times string rarr string times stringsplit into fields fields (char rarr bool) times string rarr string listsplit into tokens tokens (char rarr bool) times string rarr string list

These are based on the SML functions Substringsplitl Substringsplitr Stringfieldsand Stringtokens Character predicates are declared using special syntax for example theexpression

splitl space or hexdigit and not in set a f ( 12bcab)

gives the result lsquo( 12bc ab)rsquo

26

A8 Floating-pointThe L3 language does not provide specialised types for representing floating-point numbersHowever 32-bit (single precision) and 64-bit (double precision) bit-vector values can be treatedas floating-point numbers the following IEEE compliant encoding formats are assumed

31 30 23 22 0

s e m1 8 23

63 62 52 51 0

s e m1 11 52

Here lsquosrsquo is the sign bit (set to lsquo1rsquo for negative numbers) lsquoersquo is a biased exponent value and lsquomrsquo is thesignificand The following constants and operations are available (where lsquofprsquo stands for bits(32)or bits(64) depending on the name of the operation)

rounding modes roundTiesToEvenroundTowardPositiveroundTowardNegativeroundTowardZero

ieee_rounding

flags (record) DivideByZero InvalidOpOverflow PrecisionUnderflow

ieee_flagsrarrbool

comparison values FP_LT FP_EQ FP_GT FP_UN ieee_compare

convert format FP32_ToFP64 fp32rarrfp64convert format FP64_ToFP32 ieee_roundingtimes fp64rarrfp32convert format FP64_ToFP32_ ieee_roundingtimes fp64rarr

ieee_flagstimes fp32from integer FP32|64_FromInt ieee_roundingtimes intrarrfpto integer FP32|64_ToInt ieee_roundingtimes fprarrint optionfrom string FP32|64 stringrarrfp

negative zero FP32|64_NegZero fppositive zero FP32|64_PosZero fpnegative infinity FP32|64_NegInf fppositive infinity FP32|64_PosInf fpa quiet NaN FP32|64_qNan fpa signalling NaN FP32|64_sNan fp

is integral FP32|64_IsIntegral fprarrboolis finite FP32|64_IsFinite fprarrboolis NaN FP32|64_IsNan fprarrboolis signalling NaN FP32|64_IsSignallingNan fprarrboolis normal FP32|64_IsNormal fprarrboolis sub-normal FP32|64_IsSubnormal fprarrboolis zero FP32|64_IsZero fprarrbool

27

comparison FP32|64_Compare fptimes fprarrieee_compareequality FP32|64_Equal fptimes fprarrboolless than FP32|64_LessThan fptimes fprarrboolless than or equal FP32|64_LessEqual fptimes fprarrboolgreater than FP32|64_GreaterThan fptimes fprarrboolgreater than or equal FP32|64_GreaterEqual fptimes fprarrbool

absolute FP32|64_Abs fprarrfpnegation FP32|64_Neg fprarrfpsquare root FP32|64_Sqrt ieee_roundingtimes fprarrfp(with flags) FP32|64_Sqrt_ ieee_roundingtimes fprarrieee_flagstimes fpaddition FP32|64_Add ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Add_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpsubtraction FP32|64_Sub ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Sub_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpmultiplication FP32|64_Mul ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Mul_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpfused multiply-add FP32|64_MulAdd ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulAdd_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpfused multiply-sub FP32|64_MulSub ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulSub_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpdivision FP32|64_Div ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Div_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fp

The L3 interpreter supports evaluation for 32-bit and 64-bit floating-point expressions but onlywhen running on an x86 machine that supports SSE2 extensions (Pentium 4 and later) Thefused multiply-addsub operations can only be interpreted on machines supporting the FMAextension which came in with the 4th generation (Haswell) Intel processors These restrictionsalso apply to any Standard ML code that is generated by L3

The IEEE 754 standard permits a number of different ways to flag underflow L3 predomi-nantly supports the x86 interpretation which detects underflow after rounding However whenexporting to HOL4 it is possible to choose detection before rounding which for example issuited to ARM instruction set models

A9 Miscellaneous operationsThe following operations are available

pair constructor αtimes β rarr αtimes βfirst of pair Fst αtimes β rarr αsecond of pair Snd αtimes β rarr β

casting [middot] α rarr βinitialise a map InitMap α rarr (βrarrα)

28

option constructor Some αrarrα optionoption projection ValOf α option rarr αoption test IsSome α option rarr bool

set membership in αtimesα set rarr boolset non-membership notin αtimesα set rarr boolset insertion insert αtimesα set rarrα setset union Union α settimesα set rarrα setset intersection Intersect α settimesα set rarrα setset difference Difference α settimesα set rarrα setset subset test IsSubset α settimesα set rarr boolset cardinality Cardinality α setrarr natset from a list SetOfList α list rarrα set

empty list Nil α listlist constructor Cons αtimesα list rarr α listlist head Head α list rarr αlist tail Tail α list rarr α listlist length Length α list rarr natlist concatenation α listtimesα list rarr α listlist flatten Concat α list list rarr α listlist element Element nattimesα list rarr αlist prefix Take nattimesα list rarr α listlist drop prefix Drop nattimesα list rarr α listlist pad left PadLeft αtimes nattimesα list rarr α listlist pad right PadRight αtimes nattimesα list rarr α listlist update Update αtimes nattimesα list rarr α listlist difference Remove α listtimesα list rarr α listlist intersection RemoveExcept α listtimesα list rarr α listlist without duplicates RemoveDuplicates α listrarr α listlist membership IsMember αtimesα list rarr boollist member position IndexOf αtimesα list rarr nat option

Sets are only defined over equality types see Appendix A2 The casting map is defined overcast-able types (as represented by the polymorphic type variables α and β) these are the primitivetypes (with the exception of lsquounitrsquo) and user defined enumerated types Assume lsquoEnumrsquo and lsquoEnum2rsquoare declared with

construct Enum One Two Three construct Enum2 Four Five Six Seven

The cast operations are described in Tables 1 to 7

29

Table 1 Cast to lsquoboolrsquo

From Operation Examples

bool identity lsquo[true]boolrsquo = lsquotruersquostring parse bool lsquo[true]boolrsquo = lsquotruersquo

lsquo[false]boolrsquo = lsquofalsersquootherwise undefined

nat is not zero lsquo[0n3]boolrsquo = lsquotruersquolsquo[0n0]boolrsquo = lsquofalsersquo

int is not zero lsquo[-0i1]boolrsquo = lsquotruersquolsquo[0i0]boolrsquo = lsquofalsersquo

bool list is not zero lsquo[0s11]boolrsquo = lsquotruersquolsquo[0s0]boolrsquo = lsquofalsersquo

bits(middot) is not zero lsquo[3`3]boolrsquo = lsquotruersquolsquo[0`3]boolrsquo = lsquofalsersquo

Enum is not the first element lsquo[One]boolrsquo = lsquofalsersquolsquo[Two]boolrsquo = lsquotruersquo

Table 2 Cast to lsquostringrsquo

From Operation Examples

bool name lsquo[true]stringrsquo = lsquotruersquostring identity lsquo[hello]stringrsquo = lsquohellorsquonat decimal lsquo[0n3]stringrsquo = lsquo3rsquoint signed decimal lsquo[-0i1]stringrsquo = lsquo~1rsquobool list binary lsquo[0s11]stringrsquo = lsquo11rsquobits(middot) unsigned hexadecimal lsquo[139`8]stringrsquo = lsquo8BrsquoEnum name lsquo[One]stringrsquo = lsquoOnersquo

30

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

Constants The structure Consts provides various functions for working with L3 constantsMany of the operation in the Consts structure will be of little interest to end-users however itcan be used to display some helpful information

The function ConstslookupConst can be used to lookup an operation for example

gt ConstslookupConst Log2val it = Primitive [(bits(a) -gt bits(a) -) (nat -gt nat -)] const

Since lsquoLog2rsquo is a primitive operation only the valid types (ordered by overload priority) are showWith user operations the internal representation (definition) of the operation will be shownfor example

gt RuntimeLoadQ `unit demo () = ()`gt ConstslookupConst demoval it = Definition (Abs ([(_ (unit -))] unit -gt unit `()`) NONE 1)

Constsconst

The functions ConstslistDefinitions and ConstslistExceptions provide details of all useroperations and exceptions respectively The function lsquoConstsstatsrsquo gives a summary of all thecurrent declarations

gt Constsstats()Primitives 188Destructors 5Constructors 0Accessors 0Exceptions 0User operations 1Instruction definitions 0

Here the constructors for primitive types (such as lsquoConsrsquo) are counted under ldquoprimitivesrdquo

Types The Types structure can be used to display information relating to L3 types In partic-ular this structure provides the functions TypeslookupConst and TypeslistConsts which aredemonstrated below

gt RuntimeloadQ `construct enum One Two Three`gt TypeslistConsts()val it =

[(enumeq = true ast = false def = Constructors (Enum ltdict(3)gt) num = 0)]

(string typeconst) list

gt TypeslookupConst intval it = SOME eq = true ast = false def = BaseType num = ~1

typeconst option

18

Loading and Exporting Specifications When writing an L3 specification it is expected thatuser declarations will be contained in an L3 source file A sample instruction set specification(tinyspec) can be found in the L3 distribution subdirectory examples This specification isbased on Thackerrsquos pedagogical Tiny 3 architecture it can be loaded as follows

gt RuntimeLoadF tinyspecLoading tinyspecltTYPgt regTltTYPgt wordTmiddot middot middotltFUNgt test_progDone

The string argument to the functions RuntimeloadF and RuntimeLoadF can be in the form ofa comma separated list of files which will be loaded in order That is the call

RuntimeloadF aspec bspec

will load aspec followed by bspecThe function HolExportexport will export the current L3 specification in the form of an

HOL4 script for example

gt HolExportexport tinyraiseexception okfunction okmiddot middot middotmextend skipmunextend skipCreated file tinyScriptsmlCreated file tinyLibsmlCreated file tinyLibsigDone

The function HolExportspec provides a convenient shortcut for performing LoadF and exportusing just a single call for example HolExportspec (tinyspec tiny) will perform theload and export presented above

L3 is capable of exporting two styles of HOL specification an explicitly monadic version(based on state_transformerTheory) and a version that directly manipulates state using let-expressions (which is the default style) For example a monadic version of the Tiny specifi-cation can be exported using the command HolExportspec (tinyspec tiny monadic)Other export options include sigdocs nosigdocs (for setting HOLrsquos TheoryPPinclude_docstrace variable) bigrecords nobigrecords (for controlling HOLrsquos Datatypebig_record_size)and underflowbefore nounderflowbefore (for selecting the required IEEE 754 underflow be-haviour)

Generated HOL4 specifications are not designed to be manually edited (or human readable)To build an L3 specification script the HOL library Import is needed This library is currentlylocated in the directory $HOL_DIRexamplesl3-machine-codecommon and so adding this path tothe INCLUDES variable of a local Holmakefile is recommended The examplesl3-machine-codedirectory contains various examples of using L3 generated specifications

19

Testing Specifications Having written an L3 specification it is fairly easy to write code (inStandard ML) that runs test vectors Code for running the tinyspec example can be found inthe file run-tinyspec In this test harness the Tiny state is initialised and a small test programis loaded simply by evaluating the expression lsquoinitialize (test_prog)rsquo

It is also possible to evaluate (run) models that have been exported to HOL4 The filerun-tinysml shows how this can be accomplished for the Tiny example

20

A Primitive Types and OperationsThe primitive types are as follows

unit bool char nat int bits(middot) rounding

There are two infix type constructors lsquorsquo for pairs and lsquo-gtrsquo for maps There are also postfix typeconstructors lsquosetrsquo lsquooptionrsquo and lsquolistrsquo for example sets of strings are represented by the typelsquostring setrsquo The following sections describe these primitive types together with some detailsof associated operations The following constants and operations are available

nullary () Nil None false roundTiesToEven roundTowardNegativeroundTowardPositive roundTowardZero true

prefix - ~ Abs Cardinality Cons Difference Drop Element FP32_AbsFP32_Add FP32_Equal FP32_IsNan FP32_LessThan FP32_MulFP32_Neg FP32_Sub FP64_Abs FP64_Add FP64_Equal FP64_IsNanFP64_LessThan FP64_Mul FP64_Neg FP64_Sub FromBinStringFromDecString FromHexString Fst Head IndexOf InitMapIntersection IsAlpha IsAlphaNum IsDigit IsHexDigit IsLowerIsMember IsSome IsSubset IsUpper Length Log2 Max Min MsbQuotRem Remove RemoveDuplicates RemoveExcept ReverseSetOfList SignExtend SignedMax SignedMin Size Snd Some TailTake ToLower ToUpper Union Update ValOf ZeroExtend not

infix = ampamp + - lt lt+ lt= lt=+ ltgt == gt gt+ gt= gt=+ ^ || gtgtltlt gtgt+ ltlt gtgt and div in insert mod notin or quot rem

sdivsmodother middot ltmiddotgt middot ltmiddotmiddotgt [middot] fields splitl splitr tokens

Many arithmetic operations are overloaded Unless otherwise stated the order of selection islsquobits(middot)rsquo lsquonatrsquo lsquointrsquo and then lsquobool listrsquo

A1 UnitThe type lsquounitrsquo represents the singleton set containing the value lsquo()rsquo The primary use of thistype is as the return type for procedures

A2 BoolThe type lsquoboolrsquo represents the two element set B = lsquotruersquo lsquofalsersquo The following standardBoolean operations are available

negation not bool rarr boolconjunction and booltimes bool rarr booldisjunction or booltimes bool rarr boolequality == αtimesα rarr boolnon-equality ltgt = αtimesα rarr bool

21

The infix operators lsquoandrsquo and lsquoorrsquo are interpreted with short-circuit evaluation for example in theexpression lsquofalse and f()rsquo the value of lsquof()rsquo is not computed as the overall expression will alwaysevaluate to false This short-circuiting influences the side-effects that occur during expressionevaluation

There are two prefix symbols for logical negation (these are semantically identical) with lsquorsquobinding slightly tighter than lsquonotrsquo This distinction is becomes significant when working withequalities for example lsquonot a == brsquo is taken to be not(a = b) whereas lsquoa == brsquo is (nota) = b

Equality is only defined with respect to equality types represented here by the type variableα An equality type is any type built without the used of the map operator lsquo-gtrsquo

A3 NatThe type lsquonatrsquo represents the natural numbers N = 0 1 2 The following operations areavailable

logarithm (base two) Log2 nat rarr natminimum value Min nattimes nat rarr natmaximium value Max nattimes nat rarr natless than lt nattimes nat rarr boolgreater than gt nattimes nat rarr boolless than or equal to lt= nattimes nat rarr boolgreater than or equal to gt= nattimes nat rarr booladdition + nattimes nat rarr natsubtraction - nattimes nat rarr natmultiplication nattimes nat rarr natexponentiation nattimes nat rarr natdivision div nattimes nat rarr natmodulus mod nattimes nat rarr nat

The lsquodivrsquo and lsquomodrsquo operations satisfy the following property

foralln 0 lt n =rArr forallk k = (k div n) lowast n+ (k mod n) and (k mod n) lt n

The expressions lsquoLog2(0)rsquo lsquox div 0rsquo and lsquox mod 0rsquo are all undefined 17

A4 IntThe type lsquointrsquo represents the integers Z = Ncupminus1minus2minus3 The following operations areavailable

17The interpreter will raise an exception when attempting to evaluate them

22

unary minus - int rarr intabsolute value Abs int rarr intminimum value Min inttimes int rarr intmaximum value Max inttimes int rarr intless than lt inttimes int rarr boolgreater than gt inttimes int rarr boolless than or equal to lt= inttimes int rarr boolgreater than or equal to gt= inttimes int rarr booladdition + inttimes int rarr intsubtraction - inttimes int rarr intmultiplication inttimes int rarr intexponentiation inttimes nat rarr intquotient and remainder QuotRem inttimes int rarr inttimes intquotient quot inttimes int rarr intremainder rem inttimes int rarr intdivision div inttimes int rarr intmodulus mod inttimes int rarr int

The operation lsquoAbsrsquo gives an positive integer value for example lsquoAbs(-2)rsquo = lsquo2rsquo The integeroperations lsquoquotrsquo and lsquodivrsquo are related to natural number division as follows

i quot j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

and

i div j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(minusi) div n(j))minus 1 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i and n(i) mod n(minusj) = 0

minus z(n(i) div n(minusj))minus 1 j lt 0 and 0 le i and n(i) mod n(minusj) = 0

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

where z NrarrZ and n ZrarrN are value preserving maps The lsquoremrsquo and lsquomodrsquo operations satisfythe equations

i rem j =

iminus (i quot j) lowast j j = 0

undefined j = 0i mod j =

iminus (i div j) lowast j j = 0

undefined j = 0

A5 Bit-vectorsThe type lsquobits(n)rsquo represents fixed-width (n-bit) words also known as bit-vectors for examplebits(32) is the type of 32-bit machine words18 The bits type can be viewed as representing

18These are called double-words (dword) in the x86 architecture and simply words in the ARM architecture

23

the set Zn = 0 1 2nminus1 for some 0 lt n At the type system level no distinction is madebetween signed and unsigned words however some operations (such as orderings) have signedand unsigned variants

The following bit-vector operations are available

1rsquos complement ~ bits(n) rarr bits(n)2rsquos complement - bits(n) rarr bits(n)absolute value Abs bits(n) rarr bits(n)logarithm (base two) Log2 bits(n) rarr bits(n)zero-extend ZeroExtend bits(m) rarr bits(n)sign-extend SignExtend bits(m) rarr bits(n)reverse bits Reverse bits(n) rarr bits(n)minimum value (u) Min bits(n)times bits(n) rarr bits(n)maximum value (u) Max bits(n)times bits(n) rarr bits(n)minimum value (s) SignedMin bits(n)times bits(n) rarr bits(n)maximum value (s) SignedMax bits(n)times bits(n) rarr bits(n)widthsize Size bits(n) rarr natmost-significant (sign) bit Msb bits(n) rarr boolbit value middot ltmiddotgt bits(n)times nat rarr boolbit field middot ltmiddotmiddotgt bits(m)times nattimes nat rarr bits(n)concatenation bits(m)times bits(n) rarr bits(p)duplication ^ bits(m)times nat rarr bits(n)less than (s) lt bits(n)times bits(n) rarr boolgreater than (s) gt bits(n)times bits(n) rarr boolless than or equal to (s) lt= bits(n)times bits(n) rarr boolgreater than or equal to (s) gt= bits(n)times bits(n) rarr boolless than (u) lt+ bits(n)times bits(n) rarr boolgreater than (u) gt+ bits(n)times bits(n) rarr boolless than or equal to (u) lt=+ bits(n)times bits(n) rarr boolgreater than or equal to (u) gt=+ bits(n)times bits(n) rarr booladdition + bits(n)times bits(n) rarr bits(n)subtraction - bits(n)times bits(n) rarr bits(n)multiplication bits(n)times bits(n) rarr bits(n)quotient (s) quot bits(n)times bits(n) rarr bits(n)remained (s) rem bits(n)times bits(n) rarr bits(n)division (u) div bits(n)times bits(n) rarr bits(n)modulus (u) mod bits(n)times bits(n) rarr bits(n)division (s) sdiv bits(n)times bits(n) rarr bits(n)modulus (s) smod bits(n)times bits(n) rarr bits(n)bitwise conjunction ampamp bits(n)times bits(n) rarr bits(n)bitwise disjunction || bits(n)times bits(n) rarr bits(n)bitwise exclusive-or bits(n)times bits(n) rarr bits(n)

Unsigned operations are labelled with (u) and signed operations are labelled with (s)The shift operations support shifting by either a bit-vector value or by a natural number value

The overloading is resolved such that the lsquonatrsquo variant is selected over the lsquobits(middot)rsquo version Theshift operations are

24

left-shift ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (u) gtgt+ bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (s) gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate left ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate right gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

A number of operations are undefined depending on the types of their domain and rangeThis is detailed in the following table

Operation Undefined when

ZeroExtend(x`n)`m m lt nSignExtend(x`n)`m m lt n(x`m)ltpgt m le p(x`m)lthlgt`n n = h+ 1minus l or h lt l orm le h((xm) (yn))`p p = m+ n((x`m) ^ n)`p p = m middot n (which covers n = 0)

The type checker will fail when these conditions are obviously violated Alternatively the inter-preter may raise a runtime error when these conditions are not met

As before the expressions lsquoLog2(0)rsquo lsquox quot 0rsquo lsquox rem 0rsquo lsquox div 0rsquo and lsquox mod 0rsquo are allundefined

A6 Bit-stringsVarious bit-string operation are defined over the type lsquobool listrsquo These are listed below

bit value middot ltmiddotgt bool listtimes nat rarr boolbit field middot ltmiddotmiddotgt bool listtimes nattimes nat rarr bool listconcatenation bool listtimes bool list rarr bool listduplication ^ bool listtimes nat rarr bool listaddition + bool listtimes bool list rarr bool listbitwise conjunction ampamp bool listtimes bool list rarr bool listbitwise disjunction || bool listtimes bool list rarr bool listbitwise exclusive-or bool listtimes bool list rarr bool listleft-shift ltlt bool listtimes nat rarr bool listright-shift gtgt+ bool listtimes nat rarr bool listrotate-right gtgt bool listtimes nat rarr bool list

The bit value operation gives the truth value of a bit-string at a given bit position for example

lsquo0s1101lt0gtrsquo = lsquotruersquo lsquo0s1101lt1gtrsquo = lsquofalsersquo lsquo0s1101lt2gtrsquo = lsquotruersquolsquo0s1101lt3gtrsquo = lsquotruersquo lsquo0s1101lt4gtrsquo = lsquofalsersquo lsquo0s1101lt5gtrsquo = lsquofalsersquo

25

The least-significant bit (position zero) occurs to the right of the bit-string The bit value oper-ation gives lsquofalsersquo when the bit position is greater than the size of the bit-string

The bit field operation extracts a range of bits from a bit-string For example

lsquo0s1101lt31gtrsquo = lsquo0s110rsquo and lsquo0s1101lt52gtrsquo = lsquo0s0011rsquo

In the bit-string expression xlthlgt the size of the result is always h + 1 minus l and the result isundefined when h lt l

Bit-string addition does not require the arguments to be of the same size and it gives anon-truncated result For example

lsquo0s101 + 0s1rsquo = lsquo0s110rsquo and lsquo0s101 + 0s11rsquo = lsquo0s1000rsquo

The operation ltlt performs a left-shift for example lsquo0s1101 ltlt 2rsquo = lsquo0s110100rsquo The oper-ation lsquorsquo is bit-string concatenation and lsquo^rsquo is duplication for example

lsquo0s101 0s11rsquo = lsquo0s10111rsquo and lsquo0s101 ^ 3rsquo = lsquo0s101101101rsquo

Regular list operations work as one would expect over bit-strings for example lsquoHead (0s101)rsquois a valid expression with value lsquotruersquo

A7 Characters and StringsThe following built-in functions are available for characters and strings

is alphabetic IsAlpha char rarr boolis alpha-numeric IsAlphaNum char rarr boolis decimal digit IsDigit char rarr boolis hexadecimal digit IsHexDigit char rarr boolis lowercase IsLower char rarr boolis uppercase IsUpper char rarr boolparse binary FromBinString string rarr num optionparse decimal FromDecString string rarr num optionparse hexadecimal FromHexString string rarr num optionconvert to lowercase ToLower string rarr stringconvert to uppercase ToUpper string rarr string

The following string operations are useful for parsing

split from the left splitl (char rarr bool) times string rarr string times stringsplit from the right splitr (char rarr bool) times string rarr string times stringsplit into fields fields (char rarr bool) times string rarr string listsplit into tokens tokens (char rarr bool) times string rarr string list

These are based on the SML functions Substringsplitl Substringsplitr Stringfieldsand Stringtokens Character predicates are declared using special syntax for example theexpression

splitl space or hexdigit and not in set a f ( 12bcab)

gives the result lsquo( 12bc ab)rsquo

26

A8 Floating-pointThe L3 language does not provide specialised types for representing floating-point numbersHowever 32-bit (single precision) and 64-bit (double precision) bit-vector values can be treatedas floating-point numbers the following IEEE compliant encoding formats are assumed

31 30 23 22 0

s e m1 8 23

63 62 52 51 0

s e m1 11 52

Here lsquosrsquo is the sign bit (set to lsquo1rsquo for negative numbers) lsquoersquo is a biased exponent value and lsquomrsquo is thesignificand The following constants and operations are available (where lsquofprsquo stands for bits(32)or bits(64) depending on the name of the operation)

rounding modes roundTiesToEvenroundTowardPositiveroundTowardNegativeroundTowardZero

ieee_rounding

flags (record) DivideByZero InvalidOpOverflow PrecisionUnderflow

ieee_flagsrarrbool

comparison values FP_LT FP_EQ FP_GT FP_UN ieee_compare

convert format FP32_ToFP64 fp32rarrfp64convert format FP64_ToFP32 ieee_roundingtimes fp64rarrfp32convert format FP64_ToFP32_ ieee_roundingtimes fp64rarr

ieee_flagstimes fp32from integer FP32|64_FromInt ieee_roundingtimes intrarrfpto integer FP32|64_ToInt ieee_roundingtimes fprarrint optionfrom string FP32|64 stringrarrfp

negative zero FP32|64_NegZero fppositive zero FP32|64_PosZero fpnegative infinity FP32|64_NegInf fppositive infinity FP32|64_PosInf fpa quiet NaN FP32|64_qNan fpa signalling NaN FP32|64_sNan fp

is integral FP32|64_IsIntegral fprarrboolis finite FP32|64_IsFinite fprarrboolis NaN FP32|64_IsNan fprarrboolis signalling NaN FP32|64_IsSignallingNan fprarrboolis normal FP32|64_IsNormal fprarrboolis sub-normal FP32|64_IsSubnormal fprarrboolis zero FP32|64_IsZero fprarrbool

27

comparison FP32|64_Compare fptimes fprarrieee_compareequality FP32|64_Equal fptimes fprarrboolless than FP32|64_LessThan fptimes fprarrboolless than or equal FP32|64_LessEqual fptimes fprarrboolgreater than FP32|64_GreaterThan fptimes fprarrboolgreater than or equal FP32|64_GreaterEqual fptimes fprarrbool

absolute FP32|64_Abs fprarrfpnegation FP32|64_Neg fprarrfpsquare root FP32|64_Sqrt ieee_roundingtimes fprarrfp(with flags) FP32|64_Sqrt_ ieee_roundingtimes fprarrieee_flagstimes fpaddition FP32|64_Add ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Add_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpsubtraction FP32|64_Sub ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Sub_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpmultiplication FP32|64_Mul ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Mul_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpfused multiply-add FP32|64_MulAdd ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulAdd_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpfused multiply-sub FP32|64_MulSub ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulSub_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpdivision FP32|64_Div ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Div_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fp

The L3 interpreter supports evaluation for 32-bit and 64-bit floating-point expressions but onlywhen running on an x86 machine that supports SSE2 extensions (Pentium 4 and later) Thefused multiply-addsub operations can only be interpreted on machines supporting the FMAextension which came in with the 4th generation (Haswell) Intel processors These restrictionsalso apply to any Standard ML code that is generated by L3

The IEEE 754 standard permits a number of different ways to flag underflow L3 predomi-nantly supports the x86 interpretation which detects underflow after rounding However whenexporting to HOL4 it is possible to choose detection before rounding which for example issuited to ARM instruction set models

A9 Miscellaneous operationsThe following operations are available

pair constructor αtimes β rarr αtimes βfirst of pair Fst αtimes β rarr αsecond of pair Snd αtimes β rarr β

casting [middot] α rarr βinitialise a map InitMap α rarr (βrarrα)

28

option constructor Some αrarrα optionoption projection ValOf α option rarr αoption test IsSome α option rarr bool

set membership in αtimesα set rarr boolset non-membership notin αtimesα set rarr boolset insertion insert αtimesα set rarrα setset union Union α settimesα set rarrα setset intersection Intersect α settimesα set rarrα setset difference Difference α settimesα set rarrα setset subset test IsSubset α settimesα set rarr boolset cardinality Cardinality α setrarr natset from a list SetOfList α list rarrα set

empty list Nil α listlist constructor Cons αtimesα list rarr α listlist head Head α list rarr αlist tail Tail α list rarr α listlist length Length α list rarr natlist concatenation α listtimesα list rarr α listlist flatten Concat α list list rarr α listlist element Element nattimesα list rarr αlist prefix Take nattimesα list rarr α listlist drop prefix Drop nattimesα list rarr α listlist pad left PadLeft αtimes nattimesα list rarr α listlist pad right PadRight αtimes nattimesα list rarr α listlist update Update αtimes nattimesα list rarr α listlist difference Remove α listtimesα list rarr α listlist intersection RemoveExcept α listtimesα list rarr α listlist without duplicates RemoveDuplicates α listrarr α listlist membership IsMember αtimesα list rarr boollist member position IndexOf αtimesα list rarr nat option

Sets are only defined over equality types see Appendix A2 The casting map is defined overcast-able types (as represented by the polymorphic type variables α and β) these are the primitivetypes (with the exception of lsquounitrsquo) and user defined enumerated types Assume lsquoEnumrsquo and lsquoEnum2rsquoare declared with

construct Enum One Two Three construct Enum2 Four Five Six Seven

The cast operations are described in Tables 1 to 7

29

Table 1 Cast to lsquoboolrsquo

From Operation Examples

bool identity lsquo[true]boolrsquo = lsquotruersquostring parse bool lsquo[true]boolrsquo = lsquotruersquo

lsquo[false]boolrsquo = lsquofalsersquootherwise undefined

nat is not zero lsquo[0n3]boolrsquo = lsquotruersquolsquo[0n0]boolrsquo = lsquofalsersquo

int is not zero lsquo[-0i1]boolrsquo = lsquotruersquolsquo[0i0]boolrsquo = lsquofalsersquo

bool list is not zero lsquo[0s11]boolrsquo = lsquotruersquolsquo[0s0]boolrsquo = lsquofalsersquo

bits(middot) is not zero lsquo[3`3]boolrsquo = lsquotruersquolsquo[0`3]boolrsquo = lsquofalsersquo

Enum is not the first element lsquo[One]boolrsquo = lsquofalsersquolsquo[Two]boolrsquo = lsquotruersquo

Table 2 Cast to lsquostringrsquo

From Operation Examples

bool name lsquo[true]stringrsquo = lsquotruersquostring identity lsquo[hello]stringrsquo = lsquohellorsquonat decimal lsquo[0n3]stringrsquo = lsquo3rsquoint signed decimal lsquo[-0i1]stringrsquo = lsquo~1rsquobool list binary lsquo[0s11]stringrsquo = lsquo11rsquobits(middot) unsigned hexadecimal lsquo[139`8]stringrsquo = lsquo8BrsquoEnum name lsquo[One]stringrsquo = lsquoOnersquo

30

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

Loading and Exporting Specifications When writing an L3 specification it is expected thatuser declarations will be contained in an L3 source file A sample instruction set specification(tinyspec) can be found in the L3 distribution subdirectory examples This specification isbased on Thackerrsquos pedagogical Tiny 3 architecture it can be loaded as follows

gt RuntimeLoadF tinyspecLoading tinyspecltTYPgt regTltTYPgt wordTmiddot middot middotltFUNgt test_progDone

The string argument to the functions RuntimeloadF and RuntimeLoadF can be in the form ofa comma separated list of files which will be loaded in order That is the call

RuntimeloadF aspec bspec

will load aspec followed by bspecThe function HolExportexport will export the current L3 specification in the form of an

HOL4 script for example

gt HolExportexport tinyraiseexception okfunction okmiddot middot middotmextend skipmunextend skipCreated file tinyScriptsmlCreated file tinyLibsmlCreated file tinyLibsigDone

The function HolExportspec provides a convenient shortcut for performing LoadF and exportusing just a single call for example HolExportspec (tinyspec tiny) will perform theload and export presented above

L3 is capable of exporting two styles of HOL specification an explicitly monadic version(based on state_transformerTheory) and a version that directly manipulates state using let-expressions (which is the default style) For example a monadic version of the Tiny specifi-cation can be exported using the command HolExportspec (tinyspec tiny monadic)Other export options include sigdocs nosigdocs (for setting HOLrsquos TheoryPPinclude_docstrace variable) bigrecords nobigrecords (for controlling HOLrsquos Datatypebig_record_size)and underflowbefore nounderflowbefore (for selecting the required IEEE 754 underflow be-haviour)

Generated HOL4 specifications are not designed to be manually edited (or human readable)To build an L3 specification script the HOL library Import is needed This library is currentlylocated in the directory $HOL_DIRexamplesl3-machine-codecommon and so adding this path tothe INCLUDES variable of a local Holmakefile is recommended The examplesl3-machine-codedirectory contains various examples of using L3 generated specifications

19

Testing Specifications Having written an L3 specification it is fairly easy to write code (inStandard ML) that runs test vectors Code for running the tinyspec example can be found inthe file run-tinyspec In this test harness the Tiny state is initialised and a small test programis loaded simply by evaluating the expression lsquoinitialize (test_prog)rsquo

It is also possible to evaluate (run) models that have been exported to HOL4 The filerun-tinysml shows how this can be accomplished for the Tiny example

20

A Primitive Types and OperationsThe primitive types are as follows

unit bool char nat int bits(middot) rounding

There are two infix type constructors lsquorsquo for pairs and lsquo-gtrsquo for maps There are also postfix typeconstructors lsquosetrsquo lsquooptionrsquo and lsquolistrsquo for example sets of strings are represented by the typelsquostring setrsquo The following sections describe these primitive types together with some detailsof associated operations The following constants and operations are available

nullary () Nil None false roundTiesToEven roundTowardNegativeroundTowardPositive roundTowardZero true

prefix - ~ Abs Cardinality Cons Difference Drop Element FP32_AbsFP32_Add FP32_Equal FP32_IsNan FP32_LessThan FP32_MulFP32_Neg FP32_Sub FP64_Abs FP64_Add FP64_Equal FP64_IsNanFP64_LessThan FP64_Mul FP64_Neg FP64_Sub FromBinStringFromDecString FromHexString Fst Head IndexOf InitMapIntersection IsAlpha IsAlphaNum IsDigit IsHexDigit IsLowerIsMember IsSome IsSubset IsUpper Length Log2 Max Min MsbQuotRem Remove RemoveDuplicates RemoveExcept ReverseSetOfList SignExtend SignedMax SignedMin Size Snd Some TailTake ToLower ToUpper Union Update ValOf ZeroExtend not

infix = ampamp + - lt lt+ lt= lt=+ ltgt == gt gt+ gt= gt=+ ^ || gtgtltlt gtgt+ ltlt gtgt and div in insert mod notin or quot rem

sdivsmodother middot ltmiddotgt middot ltmiddotmiddotgt [middot] fields splitl splitr tokens

Many arithmetic operations are overloaded Unless otherwise stated the order of selection islsquobits(middot)rsquo lsquonatrsquo lsquointrsquo and then lsquobool listrsquo

A1 UnitThe type lsquounitrsquo represents the singleton set containing the value lsquo()rsquo The primary use of thistype is as the return type for procedures

A2 BoolThe type lsquoboolrsquo represents the two element set B = lsquotruersquo lsquofalsersquo The following standardBoolean operations are available

negation not bool rarr boolconjunction and booltimes bool rarr booldisjunction or booltimes bool rarr boolequality == αtimesα rarr boolnon-equality ltgt = αtimesα rarr bool

21

The infix operators lsquoandrsquo and lsquoorrsquo are interpreted with short-circuit evaluation for example in theexpression lsquofalse and f()rsquo the value of lsquof()rsquo is not computed as the overall expression will alwaysevaluate to false This short-circuiting influences the side-effects that occur during expressionevaluation

There are two prefix symbols for logical negation (these are semantically identical) with lsquorsquobinding slightly tighter than lsquonotrsquo This distinction is becomes significant when working withequalities for example lsquonot a == brsquo is taken to be not(a = b) whereas lsquoa == brsquo is (nota) = b

Equality is only defined with respect to equality types represented here by the type variableα An equality type is any type built without the used of the map operator lsquo-gtrsquo

A3 NatThe type lsquonatrsquo represents the natural numbers N = 0 1 2 The following operations areavailable

logarithm (base two) Log2 nat rarr natminimum value Min nattimes nat rarr natmaximium value Max nattimes nat rarr natless than lt nattimes nat rarr boolgreater than gt nattimes nat rarr boolless than or equal to lt= nattimes nat rarr boolgreater than or equal to gt= nattimes nat rarr booladdition + nattimes nat rarr natsubtraction - nattimes nat rarr natmultiplication nattimes nat rarr natexponentiation nattimes nat rarr natdivision div nattimes nat rarr natmodulus mod nattimes nat rarr nat

The lsquodivrsquo and lsquomodrsquo operations satisfy the following property

foralln 0 lt n =rArr forallk k = (k div n) lowast n+ (k mod n) and (k mod n) lt n

The expressions lsquoLog2(0)rsquo lsquox div 0rsquo and lsquox mod 0rsquo are all undefined 17

A4 IntThe type lsquointrsquo represents the integers Z = Ncupminus1minus2minus3 The following operations areavailable

17The interpreter will raise an exception when attempting to evaluate them

22

unary minus - int rarr intabsolute value Abs int rarr intminimum value Min inttimes int rarr intmaximum value Max inttimes int rarr intless than lt inttimes int rarr boolgreater than gt inttimes int rarr boolless than or equal to lt= inttimes int rarr boolgreater than or equal to gt= inttimes int rarr booladdition + inttimes int rarr intsubtraction - inttimes int rarr intmultiplication inttimes int rarr intexponentiation inttimes nat rarr intquotient and remainder QuotRem inttimes int rarr inttimes intquotient quot inttimes int rarr intremainder rem inttimes int rarr intdivision div inttimes int rarr intmodulus mod inttimes int rarr int

The operation lsquoAbsrsquo gives an positive integer value for example lsquoAbs(-2)rsquo = lsquo2rsquo The integeroperations lsquoquotrsquo and lsquodivrsquo are related to natural number division as follows

i quot j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

and

i div j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(minusi) div n(j))minus 1 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i and n(i) mod n(minusj) = 0

minus z(n(i) div n(minusj))minus 1 j lt 0 and 0 le i and n(i) mod n(minusj) = 0

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

where z NrarrZ and n ZrarrN are value preserving maps The lsquoremrsquo and lsquomodrsquo operations satisfythe equations

i rem j =

iminus (i quot j) lowast j j = 0

undefined j = 0i mod j =

iminus (i div j) lowast j j = 0

undefined j = 0

A5 Bit-vectorsThe type lsquobits(n)rsquo represents fixed-width (n-bit) words also known as bit-vectors for examplebits(32) is the type of 32-bit machine words18 The bits type can be viewed as representing

18These are called double-words (dword) in the x86 architecture and simply words in the ARM architecture

23

the set Zn = 0 1 2nminus1 for some 0 lt n At the type system level no distinction is madebetween signed and unsigned words however some operations (such as orderings) have signedand unsigned variants

The following bit-vector operations are available

1rsquos complement ~ bits(n) rarr bits(n)2rsquos complement - bits(n) rarr bits(n)absolute value Abs bits(n) rarr bits(n)logarithm (base two) Log2 bits(n) rarr bits(n)zero-extend ZeroExtend bits(m) rarr bits(n)sign-extend SignExtend bits(m) rarr bits(n)reverse bits Reverse bits(n) rarr bits(n)minimum value (u) Min bits(n)times bits(n) rarr bits(n)maximum value (u) Max bits(n)times bits(n) rarr bits(n)minimum value (s) SignedMin bits(n)times bits(n) rarr bits(n)maximum value (s) SignedMax bits(n)times bits(n) rarr bits(n)widthsize Size bits(n) rarr natmost-significant (sign) bit Msb bits(n) rarr boolbit value middot ltmiddotgt bits(n)times nat rarr boolbit field middot ltmiddotmiddotgt bits(m)times nattimes nat rarr bits(n)concatenation bits(m)times bits(n) rarr bits(p)duplication ^ bits(m)times nat rarr bits(n)less than (s) lt bits(n)times bits(n) rarr boolgreater than (s) gt bits(n)times bits(n) rarr boolless than or equal to (s) lt= bits(n)times bits(n) rarr boolgreater than or equal to (s) gt= bits(n)times bits(n) rarr boolless than (u) lt+ bits(n)times bits(n) rarr boolgreater than (u) gt+ bits(n)times bits(n) rarr boolless than or equal to (u) lt=+ bits(n)times bits(n) rarr boolgreater than or equal to (u) gt=+ bits(n)times bits(n) rarr booladdition + bits(n)times bits(n) rarr bits(n)subtraction - bits(n)times bits(n) rarr bits(n)multiplication bits(n)times bits(n) rarr bits(n)quotient (s) quot bits(n)times bits(n) rarr bits(n)remained (s) rem bits(n)times bits(n) rarr bits(n)division (u) div bits(n)times bits(n) rarr bits(n)modulus (u) mod bits(n)times bits(n) rarr bits(n)division (s) sdiv bits(n)times bits(n) rarr bits(n)modulus (s) smod bits(n)times bits(n) rarr bits(n)bitwise conjunction ampamp bits(n)times bits(n) rarr bits(n)bitwise disjunction || bits(n)times bits(n) rarr bits(n)bitwise exclusive-or bits(n)times bits(n) rarr bits(n)

Unsigned operations are labelled with (u) and signed operations are labelled with (s)The shift operations support shifting by either a bit-vector value or by a natural number value

The overloading is resolved such that the lsquonatrsquo variant is selected over the lsquobits(middot)rsquo version Theshift operations are

24

left-shift ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (u) gtgt+ bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (s) gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate left ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate right gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

A number of operations are undefined depending on the types of their domain and rangeThis is detailed in the following table

Operation Undefined when

ZeroExtend(x`n)`m m lt nSignExtend(x`n)`m m lt n(x`m)ltpgt m le p(x`m)lthlgt`n n = h+ 1minus l or h lt l orm le h((xm) (yn))`p p = m+ n((x`m) ^ n)`p p = m middot n (which covers n = 0)

The type checker will fail when these conditions are obviously violated Alternatively the inter-preter may raise a runtime error when these conditions are not met

As before the expressions lsquoLog2(0)rsquo lsquox quot 0rsquo lsquox rem 0rsquo lsquox div 0rsquo and lsquox mod 0rsquo are allundefined

A6 Bit-stringsVarious bit-string operation are defined over the type lsquobool listrsquo These are listed below

bit value middot ltmiddotgt bool listtimes nat rarr boolbit field middot ltmiddotmiddotgt bool listtimes nattimes nat rarr bool listconcatenation bool listtimes bool list rarr bool listduplication ^ bool listtimes nat rarr bool listaddition + bool listtimes bool list rarr bool listbitwise conjunction ampamp bool listtimes bool list rarr bool listbitwise disjunction || bool listtimes bool list rarr bool listbitwise exclusive-or bool listtimes bool list rarr bool listleft-shift ltlt bool listtimes nat rarr bool listright-shift gtgt+ bool listtimes nat rarr bool listrotate-right gtgt bool listtimes nat rarr bool list

The bit value operation gives the truth value of a bit-string at a given bit position for example

lsquo0s1101lt0gtrsquo = lsquotruersquo lsquo0s1101lt1gtrsquo = lsquofalsersquo lsquo0s1101lt2gtrsquo = lsquotruersquolsquo0s1101lt3gtrsquo = lsquotruersquo lsquo0s1101lt4gtrsquo = lsquofalsersquo lsquo0s1101lt5gtrsquo = lsquofalsersquo

25

The least-significant bit (position zero) occurs to the right of the bit-string The bit value oper-ation gives lsquofalsersquo when the bit position is greater than the size of the bit-string

The bit field operation extracts a range of bits from a bit-string For example

lsquo0s1101lt31gtrsquo = lsquo0s110rsquo and lsquo0s1101lt52gtrsquo = lsquo0s0011rsquo

In the bit-string expression xlthlgt the size of the result is always h + 1 minus l and the result isundefined when h lt l

Bit-string addition does not require the arguments to be of the same size and it gives anon-truncated result For example

lsquo0s101 + 0s1rsquo = lsquo0s110rsquo and lsquo0s101 + 0s11rsquo = lsquo0s1000rsquo

The operation ltlt performs a left-shift for example lsquo0s1101 ltlt 2rsquo = lsquo0s110100rsquo The oper-ation lsquorsquo is bit-string concatenation and lsquo^rsquo is duplication for example

lsquo0s101 0s11rsquo = lsquo0s10111rsquo and lsquo0s101 ^ 3rsquo = lsquo0s101101101rsquo

Regular list operations work as one would expect over bit-strings for example lsquoHead (0s101)rsquois a valid expression with value lsquotruersquo

A7 Characters and StringsThe following built-in functions are available for characters and strings

is alphabetic IsAlpha char rarr boolis alpha-numeric IsAlphaNum char rarr boolis decimal digit IsDigit char rarr boolis hexadecimal digit IsHexDigit char rarr boolis lowercase IsLower char rarr boolis uppercase IsUpper char rarr boolparse binary FromBinString string rarr num optionparse decimal FromDecString string rarr num optionparse hexadecimal FromHexString string rarr num optionconvert to lowercase ToLower string rarr stringconvert to uppercase ToUpper string rarr string

The following string operations are useful for parsing

split from the left splitl (char rarr bool) times string rarr string times stringsplit from the right splitr (char rarr bool) times string rarr string times stringsplit into fields fields (char rarr bool) times string rarr string listsplit into tokens tokens (char rarr bool) times string rarr string list

These are based on the SML functions Substringsplitl Substringsplitr Stringfieldsand Stringtokens Character predicates are declared using special syntax for example theexpression

splitl space or hexdigit and not in set a f ( 12bcab)

gives the result lsquo( 12bc ab)rsquo

26

A8 Floating-pointThe L3 language does not provide specialised types for representing floating-point numbersHowever 32-bit (single precision) and 64-bit (double precision) bit-vector values can be treatedas floating-point numbers the following IEEE compliant encoding formats are assumed

31 30 23 22 0

s e m1 8 23

63 62 52 51 0

s e m1 11 52

Here lsquosrsquo is the sign bit (set to lsquo1rsquo for negative numbers) lsquoersquo is a biased exponent value and lsquomrsquo is thesignificand The following constants and operations are available (where lsquofprsquo stands for bits(32)or bits(64) depending on the name of the operation)

rounding modes roundTiesToEvenroundTowardPositiveroundTowardNegativeroundTowardZero

ieee_rounding

flags (record) DivideByZero InvalidOpOverflow PrecisionUnderflow

ieee_flagsrarrbool

comparison values FP_LT FP_EQ FP_GT FP_UN ieee_compare

convert format FP32_ToFP64 fp32rarrfp64convert format FP64_ToFP32 ieee_roundingtimes fp64rarrfp32convert format FP64_ToFP32_ ieee_roundingtimes fp64rarr

ieee_flagstimes fp32from integer FP32|64_FromInt ieee_roundingtimes intrarrfpto integer FP32|64_ToInt ieee_roundingtimes fprarrint optionfrom string FP32|64 stringrarrfp

negative zero FP32|64_NegZero fppositive zero FP32|64_PosZero fpnegative infinity FP32|64_NegInf fppositive infinity FP32|64_PosInf fpa quiet NaN FP32|64_qNan fpa signalling NaN FP32|64_sNan fp

is integral FP32|64_IsIntegral fprarrboolis finite FP32|64_IsFinite fprarrboolis NaN FP32|64_IsNan fprarrboolis signalling NaN FP32|64_IsSignallingNan fprarrboolis normal FP32|64_IsNormal fprarrboolis sub-normal FP32|64_IsSubnormal fprarrboolis zero FP32|64_IsZero fprarrbool

27

comparison FP32|64_Compare fptimes fprarrieee_compareequality FP32|64_Equal fptimes fprarrboolless than FP32|64_LessThan fptimes fprarrboolless than or equal FP32|64_LessEqual fptimes fprarrboolgreater than FP32|64_GreaterThan fptimes fprarrboolgreater than or equal FP32|64_GreaterEqual fptimes fprarrbool

absolute FP32|64_Abs fprarrfpnegation FP32|64_Neg fprarrfpsquare root FP32|64_Sqrt ieee_roundingtimes fprarrfp(with flags) FP32|64_Sqrt_ ieee_roundingtimes fprarrieee_flagstimes fpaddition FP32|64_Add ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Add_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpsubtraction FP32|64_Sub ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Sub_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpmultiplication FP32|64_Mul ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Mul_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpfused multiply-add FP32|64_MulAdd ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulAdd_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpfused multiply-sub FP32|64_MulSub ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulSub_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpdivision FP32|64_Div ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Div_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fp

The L3 interpreter supports evaluation for 32-bit and 64-bit floating-point expressions but onlywhen running on an x86 machine that supports SSE2 extensions (Pentium 4 and later) Thefused multiply-addsub operations can only be interpreted on machines supporting the FMAextension which came in with the 4th generation (Haswell) Intel processors These restrictionsalso apply to any Standard ML code that is generated by L3

The IEEE 754 standard permits a number of different ways to flag underflow L3 predomi-nantly supports the x86 interpretation which detects underflow after rounding However whenexporting to HOL4 it is possible to choose detection before rounding which for example issuited to ARM instruction set models

A9 Miscellaneous operationsThe following operations are available

pair constructor αtimes β rarr αtimes βfirst of pair Fst αtimes β rarr αsecond of pair Snd αtimes β rarr β

casting [middot] α rarr βinitialise a map InitMap α rarr (βrarrα)

28

option constructor Some αrarrα optionoption projection ValOf α option rarr αoption test IsSome α option rarr bool

set membership in αtimesα set rarr boolset non-membership notin αtimesα set rarr boolset insertion insert αtimesα set rarrα setset union Union α settimesα set rarrα setset intersection Intersect α settimesα set rarrα setset difference Difference α settimesα set rarrα setset subset test IsSubset α settimesα set rarr boolset cardinality Cardinality α setrarr natset from a list SetOfList α list rarrα set

empty list Nil α listlist constructor Cons αtimesα list rarr α listlist head Head α list rarr αlist tail Tail α list rarr α listlist length Length α list rarr natlist concatenation α listtimesα list rarr α listlist flatten Concat α list list rarr α listlist element Element nattimesα list rarr αlist prefix Take nattimesα list rarr α listlist drop prefix Drop nattimesα list rarr α listlist pad left PadLeft αtimes nattimesα list rarr α listlist pad right PadRight αtimes nattimesα list rarr α listlist update Update αtimes nattimesα list rarr α listlist difference Remove α listtimesα list rarr α listlist intersection RemoveExcept α listtimesα list rarr α listlist without duplicates RemoveDuplicates α listrarr α listlist membership IsMember αtimesα list rarr boollist member position IndexOf αtimesα list rarr nat option

Sets are only defined over equality types see Appendix A2 The casting map is defined overcast-able types (as represented by the polymorphic type variables α and β) these are the primitivetypes (with the exception of lsquounitrsquo) and user defined enumerated types Assume lsquoEnumrsquo and lsquoEnum2rsquoare declared with

construct Enum One Two Three construct Enum2 Four Five Six Seven

The cast operations are described in Tables 1 to 7

29

Table 1 Cast to lsquoboolrsquo

From Operation Examples

bool identity lsquo[true]boolrsquo = lsquotruersquostring parse bool lsquo[true]boolrsquo = lsquotruersquo

lsquo[false]boolrsquo = lsquofalsersquootherwise undefined

nat is not zero lsquo[0n3]boolrsquo = lsquotruersquolsquo[0n0]boolrsquo = lsquofalsersquo

int is not zero lsquo[-0i1]boolrsquo = lsquotruersquolsquo[0i0]boolrsquo = lsquofalsersquo

bool list is not zero lsquo[0s11]boolrsquo = lsquotruersquolsquo[0s0]boolrsquo = lsquofalsersquo

bits(middot) is not zero lsquo[3`3]boolrsquo = lsquotruersquolsquo[0`3]boolrsquo = lsquofalsersquo

Enum is not the first element lsquo[One]boolrsquo = lsquofalsersquolsquo[Two]boolrsquo = lsquotruersquo

Table 2 Cast to lsquostringrsquo

From Operation Examples

bool name lsquo[true]stringrsquo = lsquotruersquostring identity lsquo[hello]stringrsquo = lsquohellorsquonat decimal lsquo[0n3]stringrsquo = lsquo3rsquoint signed decimal lsquo[-0i1]stringrsquo = lsquo~1rsquobool list binary lsquo[0s11]stringrsquo = lsquo11rsquobits(middot) unsigned hexadecimal lsquo[139`8]stringrsquo = lsquo8BrsquoEnum name lsquo[One]stringrsquo = lsquoOnersquo

30

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

Testing Specifications Having written an L3 specification it is fairly easy to write code (inStandard ML) that runs test vectors Code for running the tinyspec example can be found inthe file run-tinyspec In this test harness the Tiny state is initialised and a small test programis loaded simply by evaluating the expression lsquoinitialize (test_prog)rsquo

It is also possible to evaluate (run) models that have been exported to HOL4 The filerun-tinysml shows how this can be accomplished for the Tiny example

20

A Primitive Types and OperationsThe primitive types are as follows

unit bool char nat int bits(middot) rounding

There are two infix type constructors lsquorsquo for pairs and lsquo-gtrsquo for maps There are also postfix typeconstructors lsquosetrsquo lsquooptionrsquo and lsquolistrsquo for example sets of strings are represented by the typelsquostring setrsquo The following sections describe these primitive types together with some detailsof associated operations The following constants and operations are available

nullary () Nil None false roundTiesToEven roundTowardNegativeroundTowardPositive roundTowardZero true

prefix - ~ Abs Cardinality Cons Difference Drop Element FP32_AbsFP32_Add FP32_Equal FP32_IsNan FP32_LessThan FP32_MulFP32_Neg FP32_Sub FP64_Abs FP64_Add FP64_Equal FP64_IsNanFP64_LessThan FP64_Mul FP64_Neg FP64_Sub FromBinStringFromDecString FromHexString Fst Head IndexOf InitMapIntersection IsAlpha IsAlphaNum IsDigit IsHexDigit IsLowerIsMember IsSome IsSubset IsUpper Length Log2 Max Min MsbQuotRem Remove RemoveDuplicates RemoveExcept ReverseSetOfList SignExtend SignedMax SignedMin Size Snd Some TailTake ToLower ToUpper Union Update ValOf ZeroExtend not

infix = ampamp + - lt lt+ lt= lt=+ ltgt == gt gt+ gt= gt=+ ^ || gtgtltlt gtgt+ ltlt gtgt and div in insert mod notin or quot rem

sdivsmodother middot ltmiddotgt middot ltmiddotmiddotgt [middot] fields splitl splitr tokens

Many arithmetic operations are overloaded Unless otherwise stated the order of selection islsquobits(middot)rsquo lsquonatrsquo lsquointrsquo and then lsquobool listrsquo

A1 UnitThe type lsquounitrsquo represents the singleton set containing the value lsquo()rsquo The primary use of thistype is as the return type for procedures

A2 BoolThe type lsquoboolrsquo represents the two element set B = lsquotruersquo lsquofalsersquo The following standardBoolean operations are available

negation not bool rarr boolconjunction and booltimes bool rarr booldisjunction or booltimes bool rarr boolequality == αtimesα rarr boolnon-equality ltgt = αtimesα rarr bool

21

The infix operators lsquoandrsquo and lsquoorrsquo are interpreted with short-circuit evaluation for example in theexpression lsquofalse and f()rsquo the value of lsquof()rsquo is not computed as the overall expression will alwaysevaluate to false This short-circuiting influences the side-effects that occur during expressionevaluation

There are two prefix symbols for logical negation (these are semantically identical) with lsquorsquobinding slightly tighter than lsquonotrsquo This distinction is becomes significant when working withequalities for example lsquonot a == brsquo is taken to be not(a = b) whereas lsquoa == brsquo is (nota) = b

Equality is only defined with respect to equality types represented here by the type variableα An equality type is any type built without the used of the map operator lsquo-gtrsquo

A3 NatThe type lsquonatrsquo represents the natural numbers N = 0 1 2 The following operations areavailable

logarithm (base two) Log2 nat rarr natminimum value Min nattimes nat rarr natmaximium value Max nattimes nat rarr natless than lt nattimes nat rarr boolgreater than gt nattimes nat rarr boolless than or equal to lt= nattimes nat rarr boolgreater than or equal to gt= nattimes nat rarr booladdition + nattimes nat rarr natsubtraction - nattimes nat rarr natmultiplication nattimes nat rarr natexponentiation nattimes nat rarr natdivision div nattimes nat rarr natmodulus mod nattimes nat rarr nat

The lsquodivrsquo and lsquomodrsquo operations satisfy the following property

foralln 0 lt n =rArr forallk k = (k div n) lowast n+ (k mod n) and (k mod n) lt n

The expressions lsquoLog2(0)rsquo lsquox div 0rsquo and lsquox mod 0rsquo are all undefined 17

A4 IntThe type lsquointrsquo represents the integers Z = Ncupminus1minus2minus3 The following operations areavailable

17The interpreter will raise an exception when attempting to evaluate them

22

unary minus - int rarr intabsolute value Abs int rarr intminimum value Min inttimes int rarr intmaximum value Max inttimes int rarr intless than lt inttimes int rarr boolgreater than gt inttimes int rarr boolless than or equal to lt= inttimes int rarr boolgreater than or equal to gt= inttimes int rarr booladdition + inttimes int rarr intsubtraction - inttimes int rarr intmultiplication inttimes int rarr intexponentiation inttimes nat rarr intquotient and remainder QuotRem inttimes int rarr inttimes intquotient quot inttimes int rarr intremainder rem inttimes int rarr intdivision div inttimes int rarr intmodulus mod inttimes int rarr int

The operation lsquoAbsrsquo gives an positive integer value for example lsquoAbs(-2)rsquo = lsquo2rsquo The integeroperations lsquoquotrsquo and lsquodivrsquo are related to natural number division as follows

i quot j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

and

i div j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(minusi) div n(j))minus 1 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i and n(i) mod n(minusj) = 0

minus z(n(i) div n(minusj))minus 1 j lt 0 and 0 le i and n(i) mod n(minusj) = 0

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

where z NrarrZ and n ZrarrN are value preserving maps The lsquoremrsquo and lsquomodrsquo operations satisfythe equations

i rem j =

iminus (i quot j) lowast j j = 0

undefined j = 0i mod j =

iminus (i div j) lowast j j = 0

undefined j = 0

A5 Bit-vectorsThe type lsquobits(n)rsquo represents fixed-width (n-bit) words also known as bit-vectors for examplebits(32) is the type of 32-bit machine words18 The bits type can be viewed as representing

18These are called double-words (dword) in the x86 architecture and simply words in the ARM architecture

23

the set Zn = 0 1 2nminus1 for some 0 lt n At the type system level no distinction is madebetween signed and unsigned words however some operations (such as orderings) have signedand unsigned variants

The following bit-vector operations are available

1rsquos complement ~ bits(n) rarr bits(n)2rsquos complement - bits(n) rarr bits(n)absolute value Abs bits(n) rarr bits(n)logarithm (base two) Log2 bits(n) rarr bits(n)zero-extend ZeroExtend bits(m) rarr bits(n)sign-extend SignExtend bits(m) rarr bits(n)reverse bits Reverse bits(n) rarr bits(n)minimum value (u) Min bits(n)times bits(n) rarr bits(n)maximum value (u) Max bits(n)times bits(n) rarr bits(n)minimum value (s) SignedMin bits(n)times bits(n) rarr bits(n)maximum value (s) SignedMax bits(n)times bits(n) rarr bits(n)widthsize Size bits(n) rarr natmost-significant (sign) bit Msb bits(n) rarr boolbit value middot ltmiddotgt bits(n)times nat rarr boolbit field middot ltmiddotmiddotgt bits(m)times nattimes nat rarr bits(n)concatenation bits(m)times bits(n) rarr bits(p)duplication ^ bits(m)times nat rarr bits(n)less than (s) lt bits(n)times bits(n) rarr boolgreater than (s) gt bits(n)times bits(n) rarr boolless than or equal to (s) lt= bits(n)times bits(n) rarr boolgreater than or equal to (s) gt= bits(n)times bits(n) rarr boolless than (u) lt+ bits(n)times bits(n) rarr boolgreater than (u) gt+ bits(n)times bits(n) rarr boolless than or equal to (u) lt=+ bits(n)times bits(n) rarr boolgreater than or equal to (u) gt=+ bits(n)times bits(n) rarr booladdition + bits(n)times bits(n) rarr bits(n)subtraction - bits(n)times bits(n) rarr bits(n)multiplication bits(n)times bits(n) rarr bits(n)quotient (s) quot bits(n)times bits(n) rarr bits(n)remained (s) rem bits(n)times bits(n) rarr bits(n)division (u) div bits(n)times bits(n) rarr bits(n)modulus (u) mod bits(n)times bits(n) rarr bits(n)division (s) sdiv bits(n)times bits(n) rarr bits(n)modulus (s) smod bits(n)times bits(n) rarr bits(n)bitwise conjunction ampamp bits(n)times bits(n) rarr bits(n)bitwise disjunction || bits(n)times bits(n) rarr bits(n)bitwise exclusive-or bits(n)times bits(n) rarr bits(n)

Unsigned operations are labelled with (u) and signed operations are labelled with (s)The shift operations support shifting by either a bit-vector value or by a natural number value

The overloading is resolved such that the lsquonatrsquo variant is selected over the lsquobits(middot)rsquo version Theshift operations are

24

left-shift ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (u) gtgt+ bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (s) gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate left ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate right gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

A number of operations are undefined depending on the types of their domain and rangeThis is detailed in the following table

Operation Undefined when

ZeroExtend(x`n)`m m lt nSignExtend(x`n)`m m lt n(x`m)ltpgt m le p(x`m)lthlgt`n n = h+ 1minus l or h lt l orm le h((xm) (yn))`p p = m+ n((x`m) ^ n)`p p = m middot n (which covers n = 0)

The type checker will fail when these conditions are obviously violated Alternatively the inter-preter may raise a runtime error when these conditions are not met

As before the expressions lsquoLog2(0)rsquo lsquox quot 0rsquo lsquox rem 0rsquo lsquox div 0rsquo and lsquox mod 0rsquo are allundefined

A6 Bit-stringsVarious bit-string operation are defined over the type lsquobool listrsquo These are listed below

bit value middot ltmiddotgt bool listtimes nat rarr boolbit field middot ltmiddotmiddotgt bool listtimes nattimes nat rarr bool listconcatenation bool listtimes bool list rarr bool listduplication ^ bool listtimes nat rarr bool listaddition + bool listtimes bool list rarr bool listbitwise conjunction ampamp bool listtimes bool list rarr bool listbitwise disjunction || bool listtimes bool list rarr bool listbitwise exclusive-or bool listtimes bool list rarr bool listleft-shift ltlt bool listtimes nat rarr bool listright-shift gtgt+ bool listtimes nat rarr bool listrotate-right gtgt bool listtimes nat rarr bool list

The bit value operation gives the truth value of a bit-string at a given bit position for example

lsquo0s1101lt0gtrsquo = lsquotruersquo lsquo0s1101lt1gtrsquo = lsquofalsersquo lsquo0s1101lt2gtrsquo = lsquotruersquolsquo0s1101lt3gtrsquo = lsquotruersquo lsquo0s1101lt4gtrsquo = lsquofalsersquo lsquo0s1101lt5gtrsquo = lsquofalsersquo

25

The least-significant bit (position zero) occurs to the right of the bit-string The bit value oper-ation gives lsquofalsersquo when the bit position is greater than the size of the bit-string

The bit field operation extracts a range of bits from a bit-string For example

lsquo0s1101lt31gtrsquo = lsquo0s110rsquo and lsquo0s1101lt52gtrsquo = lsquo0s0011rsquo

In the bit-string expression xlthlgt the size of the result is always h + 1 minus l and the result isundefined when h lt l

Bit-string addition does not require the arguments to be of the same size and it gives anon-truncated result For example

lsquo0s101 + 0s1rsquo = lsquo0s110rsquo and lsquo0s101 + 0s11rsquo = lsquo0s1000rsquo

The operation ltlt performs a left-shift for example lsquo0s1101 ltlt 2rsquo = lsquo0s110100rsquo The oper-ation lsquorsquo is bit-string concatenation and lsquo^rsquo is duplication for example

lsquo0s101 0s11rsquo = lsquo0s10111rsquo and lsquo0s101 ^ 3rsquo = lsquo0s101101101rsquo

Regular list operations work as one would expect over bit-strings for example lsquoHead (0s101)rsquois a valid expression with value lsquotruersquo

A7 Characters and StringsThe following built-in functions are available for characters and strings

is alphabetic IsAlpha char rarr boolis alpha-numeric IsAlphaNum char rarr boolis decimal digit IsDigit char rarr boolis hexadecimal digit IsHexDigit char rarr boolis lowercase IsLower char rarr boolis uppercase IsUpper char rarr boolparse binary FromBinString string rarr num optionparse decimal FromDecString string rarr num optionparse hexadecimal FromHexString string rarr num optionconvert to lowercase ToLower string rarr stringconvert to uppercase ToUpper string rarr string

The following string operations are useful for parsing

split from the left splitl (char rarr bool) times string rarr string times stringsplit from the right splitr (char rarr bool) times string rarr string times stringsplit into fields fields (char rarr bool) times string rarr string listsplit into tokens tokens (char rarr bool) times string rarr string list

These are based on the SML functions Substringsplitl Substringsplitr Stringfieldsand Stringtokens Character predicates are declared using special syntax for example theexpression

splitl space or hexdigit and not in set a f ( 12bcab)

gives the result lsquo( 12bc ab)rsquo

26

A8 Floating-pointThe L3 language does not provide specialised types for representing floating-point numbersHowever 32-bit (single precision) and 64-bit (double precision) bit-vector values can be treatedas floating-point numbers the following IEEE compliant encoding formats are assumed

31 30 23 22 0

s e m1 8 23

63 62 52 51 0

s e m1 11 52

Here lsquosrsquo is the sign bit (set to lsquo1rsquo for negative numbers) lsquoersquo is a biased exponent value and lsquomrsquo is thesignificand The following constants and operations are available (where lsquofprsquo stands for bits(32)or bits(64) depending on the name of the operation)

rounding modes roundTiesToEvenroundTowardPositiveroundTowardNegativeroundTowardZero

ieee_rounding

flags (record) DivideByZero InvalidOpOverflow PrecisionUnderflow

ieee_flagsrarrbool

comparison values FP_LT FP_EQ FP_GT FP_UN ieee_compare

convert format FP32_ToFP64 fp32rarrfp64convert format FP64_ToFP32 ieee_roundingtimes fp64rarrfp32convert format FP64_ToFP32_ ieee_roundingtimes fp64rarr

ieee_flagstimes fp32from integer FP32|64_FromInt ieee_roundingtimes intrarrfpto integer FP32|64_ToInt ieee_roundingtimes fprarrint optionfrom string FP32|64 stringrarrfp

negative zero FP32|64_NegZero fppositive zero FP32|64_PosZero fpnegative infinity FP32|64_NegInf fppositive infinity FP32|64_PosInf fpa quiet NaN FP32|64_qNan fpa signalling NaN FP32|64_sNan fp

is integral FP32|64_IsIntegral fprarrboolis finite FP32|64_IsFinite fprarrboolis NaN FP32|64_IsNan fprarrboolis signalling NaN FP32|64_IsSignallingNan fprarrboolis normal FP32|64_IsNormal fprarrboolis sub-normal FP32|64_IsSubnormal fprarrboolis zero FP32|64_IsZero fprarrbool

27

comparison FP32|64_Compare fptimes fprarrieee_compareequality FP32|64_Equal fptimes fprarrboolless than FP32|64_LessThan fptimes fprarrboolless than or equal FP32|64_LessEqual fptimes fprarrboolgreater than FP32|64_GreaterThan fptimes fprarrboolgreater than or equal FP32|64_GreaterEqual fptimes fprarrbool

absolute FP32|64_Abs fprarrfpnegation FP32|64_Neg fprarrfpsquare root FP32|64_Sqrt ieee_roundingtimes fprarrfp(with flags) FP32|64_Sqrt_ ieee_roundingtimes fprarrieee_flagstimes fpaddition FP32|64_Add ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Add_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpsubtraction FP32|64_Sub ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Sub_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpmultiplication FP32|64_Mul ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Mul_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpfused multiply-add FP32|64_MulAdd ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulAdd_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpfused multiply-sub FP32|64_MulSub ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulSub_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpdivision FP32|64_Div ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Div_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fp

The L3 interpreter supports evaluation for 32-bit and 64-bit floating-point expressions but onlywhen running on an x86 machine that supports SSE2 extensions (Pentium 4 and later) Thefused multiply-addsub operations can only be interpreted on machines supporting the FMAextension which came in with the 4th generation (Haswell) Intel processors These restrictionsalso apply to any Standard ML code that is generated by L3

The IEEE 754 standard permits a number of different ways to flag underflow L3 predomi-nantly supports the x86 interpretation which detects underflow after rounding However whenexporting to HOL4 it is possible to choose detection before rounding which for example issuited to ARM instruction set models

A9 Miscellaneous operationsThe following operations are available

pair constructor αtimes β rarr αtimes βfirst of pair Fst αtimes β rarr αsecond of pair Snd αtimes β rarr β

casting [middot] α rarr βinitialise a map InitMap α rarr (βrarrα)

28

option constructor Some αrarrα optionoption projection ValOf α option rarr αoption test IsSome α option rarr bool

set membership in αtimesα set rarr boolset non-membership notin αtimesα set rarr boolset insertion insert αtimesα set rarrα setset union Union α settimesα set rarrα setset intersection Intersect α settimesα set rarrα setset difference Difference α settimesα set rarrα setset subset test IsSubset α settimesα set rarr boolset cardinality Cardinality α setrarr natset from a list SetOfList α list rarrα set

empty list Nil α listlist constructor Cons αtimesα list rarr α listlist head Head α list rarr αlist tail Tail α list rarr α listlist length Length α list rarr natlist concatenation α listtimesα list rarr α listlist flatten Concat α list list rarr α listlist element Element nattimesα list rarr αlist prefix Take nattimesα list rarr α listlist drop prefix Drop nattimesα list rarr α listlist pad left PadLeft αtimes nattimesα list rarr α listlist pad right PadRight αtimes nattimesα list rarr α listlist update Update αtimes nattimesα list rarr α listlist difference Remove α listtimesα list rarr α listlist intersection RemoveExcept α listtimesα list rarr α listlist without duplicates RemoveDuplicates α listrarr α listlist membership IsMember αtimesα list rarr boollist member position IndexOf αtimesα list rarr nat option

Sets are only defined over equality types see Appendix A2 The casting map is defined overcast-able types (as represented by the polymorphic type variables α and β) these are the primitivetypes (with the exception of lsquounitrsquo) and user defined enumerated types Assume lsquoEnumrsquo and lsquoEnum2rsquoare declared with

construct Enum One Two Three construct Enum2 Four Five Six Seven

The cast operations are described in Tables 1 to 7

29

Table 1 Cast to lsquoboolrsquo

From Operation Examples

bool identity lsquo[true]boolrsquo = lsquotruersquostring parse bool lsquo[true]boolrsquo = lsquotruersquo

lsquo[false]boolrsquo = lsquofalsersquootherwise undefined

nat is not zero lsquo[0n3]boolrsquo = lsquotruersquolsquo[0n0]boolrsquo = lsquofalsersquo

int is not zero lsquo[-0i1]boolrsquo = lsquotruersquolsquo[0i0]boolrsquo = lsquofalsersquo

bool list is not zero lsquo[0s11]boolrsquo = lsquotruersquolsquo[0s0]boolrsquo = lsquofalsersquo

bits(middot) is not zero lsquo[3`3]boolrsquo = lsquotruersquolsquo[0`3]boolrsquo = lsquofalsersquo

Enum is not the first element lsquo[One]boolrsquo = lsquofalsersquolsquo[Two]boolrsquo = lsquotruersquo

Table 2 Cast to lsquostringrsquo

From Operation Examples

bool name lsquo[true]stringrsquo = lsquotruersquostring identity lsquo[hello]stringrsquo = lsquohellorsquonat decimal lsquo[0n3]stringrsquo = lsquo3rsquoint signed decimal lsquo[-0i1]stringrsquo = lsquo~1rsquobool list binary lsquo[0s11]stringrsquo = lsquo11rsquobits(middot) unsigned hexadecimal lsquo[139`8]stringrsquo = lsquo8BrsquoEnum name lsquo[One]stringrsquo = lsquoOnersquo

30

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

A Primitive Types and OperationsThe primitive types are as follows

unit bool char nat int bits(middot) rounding

There are two infix type constructors lsquorsquo for pairs and lsquo-gtrsquo for maps There are also postfix typeconstructors lsquosetrsquo lsquooptionrsquo and lsquolistrsquo for example sets of strings are represented by the typelsquostring setrsquo The following sections describe these primitive types together with some detailsof associated operations The following constants and operations are available

nullary () Nil None false roundTiesToEven roundTowardNegativeroundTowardPositive roundTowardZero true

prefix - ~ Abs Cardinality Cons Difference Drop Element FP32_AbsFP32_Add FP32_Equal FP32_IsNan FP32_LessThan FP32_MulFP32_Neg FP32_Sub FP64_Abs FP64_Add FP64_Equal FP64_IsNanFP64_LessThan FP64_Mul FP64_Neg FP64_Sub FromBinStringFromDecString FromHexString Fst Head IndexOf InitMapIntersection IsAlpha IsAlphaNum IsDigit IsHexDigit IsLowerIsMember IsSome IsSubset IsUpper Length Log2 Max Min MsbQuotRem Remove RemoveDuplicates RemoveExcept ReverseSetOfList SignExtend SignedMax SignedMin Size Snd Some TailTake ToLower ToUpper Union Update ValOf ZeroExtend not

infix = ampamp + - lt lt+ lt= lt=+ ltgt == gt gt+ gt= gt=+ ^ || gtgtltlt gtgt+ ltlt gtgt and div in insert mod notin or quot rem

sdivsmodother middot ltmiddotgt middot ltmiddotmiddotgt [middot] fields splitl splitr tokens

Many arithmetic operations are overloaded Unless otherwise stated the order of selection islsquobits(middot)rsquo lsquonatrsquo lsquointrsquo and then lsquobool listrsquo

A1 UnitThe type lsquounitrsquo represents the singleton set containing the value lsquo()rsquo The primary use of thistype is as the return type for procedures

A2 BoolThe type lsquoboolrsquo represents the two element set B = lsquotruersquo lsquofalsersquo The following standardBoolean operations are available

negation not bool rarr boolconjunction and booltimes bool rarr booldisjunction or booltimes bool rarr boolequality == αtimesα rarr boolnon-equality ltgt = αtimesα rarr bool

21

The infix operators lsquoandrsquo and lsquoorrsquo are interpreted with short-circuit evaluation for example in theexpression lsquofalse and f()rsquo the value of lsquof()rsquo is not computed as the overall expression will alwaysevaluate to false This short-circuiting influences the side-effects that occur during expressionevaluation

There are two prefix symbols for logical negation (these are semantically identical) with lsquorsquobinding slightly tighter than lsquonotrsquo This distinction is becomes significant when working withequalities for example lsquonot a == brsquo is taken to be not(a = b) whereas lsquoa == brsquo is (nota) = b

Equality is only defined with respect to equality types represented here by the type variableα An equality type is any type built without the used of the map operator lsquo-gtrsquo

A3 NatThe type lsquonatrsquo represents the natural numbers N = 0 1 2 The following operations areavailable

logarithm (base two) Log2 nat rarr natminimum value Min nattimes nat rarr natmaximium value Max nattimes nat rarr natless than lt nattimes nat rarr boolgreater than gt nattimes nat rarr boolless than or equal to lt= nattimes nat rarr boolgreater than or equal to gt= nattimes nat rarr booladdition + nattimes nat rarr natsubtraction - nattimes nat rarr natmultiplication nattimes nat rarr natexponentiation nattimes nat rarr natdivision div nattimes nat rarr natmodulus mod nattimes nat rarr nat

The lsquodivrsquo and lsquomodrsquo operations satisfy the following property

foralln 0 lt n =rArr forallk k = (k div n) lowast n+ (k mod n) and (k mod n) lt n

The expressions lsquoLog2(0)rsquo lsquox div 0rsquo and lsquox mod 0rsquo are all undefined 17

A4 IntThe type lsquointrsquo represents the integers Z = Ncupminus1minus2minus3 The following operations areavailable

17The interpreter will raise an exception when attempting to evaluate them

22

unary minus - int rarr intabsolute value Abs int rarr intminimum value Min inttimes int rarr intmaximum value Max inttimes int rarr intless than lt inttimes int rarr boolgreater than gt inttimes int rarr boolless than or equal to lt= inttimes int rarr boolgreater than or equal to gt= inttimes int rarr booladdition + inttimes int rarr intsubtraction - inttimes int rarr intmultiplication inttimes int rarr intexponentiation inttimes nat rarr intquotient and remainder QuotRem inttimes int rarr inttimes intquotient quot inttimes int rarr intremainder rem inttimes int rarr intdivision div inttimes int rarr intmodulus mod inttimes int rarr int

The operation lsquoAbsrsquo gives an positive integer value for example lsquoAbs(-2)rsquo = lsquo2rsquo The integeroperations lsquoquotrsquo and lsquodivrsquo are related to natural number division as follows

i quot j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

and

i div j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(minusi) div n(j))minus 1 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i and n(i) mod n(minusj) = 0

minus z(n(i) div n(minusj))minus 1 j lt 0 and 0 le i and n(i) mod n(minusj) = 0

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

where z NrarrZ and n ZrarrN are value preserving maps The lsquoremrsquo and lsquomodrsquo operations satisfythe equations

i rem j =

iminus (i quot j) lowast j j = 0

undefined j = 0i mod j =

iminus (i div j) lowast j j = 0

undefined j = 0

A5 Bit-vectorsThe type lsquobits(n)rsquo represents fixed-width (n-bit) words also known as bit-vectors for examplebits(32) is the type of 32-bit machine words18 The bits type can be viewed as representing

18These are called double-words (dword) in the x86 architecture and simply words in the ARM architecture

23

the set Zn = 0 1 2nminus1 for some 0 lt n At the type system level no distinction is madebetween signed and unsigned words however some operations (such as orderings) have signedand unsigned variants

The following bit-vector operations are available

1rsquos complement ~ bits(n) rarr bits(n)2rsquos complement - bits(n) rarr bits(n)absolute value Abs bits(n) rarr bits(n)logarithm (base two) Log2 bits(n) rarr bits(n)zero-extend ZeroExtend bits(m) rarr bits(n)sign-extend SignExtend bits(m) rarr bits(n)reverse bits Reverse bits(n) rarr bits(n)minimum value (u) Min bits(n)times bits(n) rarr bits(n)maximum value (u) Max bits(n)times bits(n) rarr bits(n)minimum value (s) SignedMin bits(n)times bits(n) rarr bits(n)maximum value (s) SignedMax bits(n)times bits(n) rarr bits(n)widthsize Size bits(n) rarr natmost-significant (sign) bit Msb bits(n) rarr boolbit value middot ltmiddotgt bits(n)times nat rarr boolbit field middot ltmiddotmiddotgt bits(m)times nattimes nat rarr bits(n)concatenation bits(m)times bits(n) rarr bits(p)duplication ^ bits(m)times nat rarr bits(n)less than (s) lt bits(n)times bits(n) rarr boolgreater than (s) gt bits(n)times bits(n) rarr boolless than or equal to (s) lt= bits(n)times bits(n) rarr boolgreater than or equal to (s) gt= bits(n)times bits(n) rarr boolless than (u) lt+ bits(n)times bits(n) rarr boolgreater than (u) gt+ bits(n)times bits(n) rarr boolless than or equal to (u) lt=+ bits(n)times bits(n) rarr boolgreater than or equal to (u) gt=+ bits(n)times bits(n) rarr booladdition + bits(n)times bits(n) rarr bits(n)subtraction - bits(n)times bits(n) rarr bits(n)multiplication bits(n)times bits(n) rarr bits(n)quotient (s) quot bits(n)times bits(n) rarr bits(n)remained (s) rem bits(n)times bits(n) rarr bits(n)division (u) div bits(n)times bits(n) rarr bits(n)modulus (u) mod bits(n)times bits(n) rarr bits(n)division (s) sdiv bits(n)times bits(n) rarr bits(n)modulus (s) smod bits(n)times bits(n) rarr bits(n)bitwise conjunction ampamp bits(n)times bits(n) rarr bits(n)bitwise disjunction || bits(n)times bits(n) rarr bits(n)bitwise exclusive-or bits(n)times bits(n) rarr bits(n)

Unsigned operations are labelled with (u) and signed operations are labelled with (s)The shift operations support shifting by either a bit-vector value or by a natural number value

The overloading is resolved such that the lsquonatrsquo variant is selected over the lsquobits(middot)rsquo version Theshift operations are

24

left-shift ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (u) gtgt+ bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (s) gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate left ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate right gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

A number of operations are undefined depending on the types of their domain and rangeThis is detailed in the following table

Operation Undefined when

ZeroExtend(x`n)`m m lt nSignExtend(x`n)`m m lt n(x`m)ltpgt m le p(x`m)lthlgt`n n = h+ 1minus l or h lt l orm le h((xm) (yn))`p p = m+ n((x`m) ^ n)`p p = m middot n (which covers n = 0)

The type checker will fail when these conditions are obviously violated Alternatively the inter-preter may raise a runtime error when these conditions are not met

As before the expressions lsquoLog2(0)rsquo lsquox quot 0rsquo lsquox rem 0rsquo lsquox div 0rsquo and lsquox mod 0rsquo are allundefined

A6 Bit-stringsVarious bit-string operation are defined over the type lsquobool listrsquo These are listed below

bit value middot ltmiddotgt bool listtimes nat rarr boolbit field middot ltmiddotmiddotgt bool listtimes nattimes nat rarr bool listconcatenation bool listtimes bool list rarr bool listduplication ^ bool listtimes nat rarr bool listaddition + bool listtimes bool list rarr bool listbitwise conjunction ampamp bool listtimes bool list rarr bool listbitwise disjunction || bool listtimes bool list rarr bool listbitwise exclusive-or bool listtimes bool list rarr bool listleft-shift ltlt bool listtimes nat rarr bool listright-shift gtgt+ bool listtimes nat rarr bool listrotate-right gtgt bool listtimes nat rarr bool list

The bit value operation gives the truth value of a bit-string at a given bit position for example

lsquo0s1101lt0gtrsquo = lsquotruersquo lsquo0s1101lt1gtrsquo = lsquofalsersquo lsquo0s1101lt2gtrsquo = lsquotruersquolsquo0s1101lt3gtrsquo = lsquotruersquo lsquo0s1101lt4gtrsquo = lsquofalsersquo lsquo0s1101lt5gtrsquo = lsquofalsersquo

25

The least-significant bit (position zero) occurs to the right of the bit-string The bit value oper-ation gives lsquofalsersquo when the bit position is greater than the size of the bit-string

The bit field operation extracts a range of bits from a bit-string For example

lsquo0s1101lt31gtrsquo = lsquo0s110rsquo and lsquo0s1101lt52gtrsquo = lsquo0s0011rsquo

In the bit-string expression xlthlgt the size of the result is always h + 1 minus l and the result isundefined when h lt l

Bit-string addition does not require the arguments to be of the same size and it gives anon-truncated result For example

lsquo0s101 + 0s1rsquo = lsquo0s110rsquo and lsquo0s101 + 0s11rsquo = lsquo0s1000rsquo

The operation ltlt performs a left-shift for example lsquo0s1101 ltlt 2rsquo = lsquo0s110100rsquo The oper-ation lsquorsquo is bit-string concatenation and lsquo^rsquo is duplication for example

lsquo0s101 0s11rsquo = lsquo0s10111rsquo and lsquo0s101 ^ 3rsquo = lsquo0s101101101rsquo

Regular list operations work as one would expect over bit-strings for example lsquoHead (0s101)rsquois a valid expression with value lsquotruersquo

A7 Characters and StringsThe following built-in functions are available for characters and strings

is alphabetic IsAlpha char rarr boolis alpha-numeric IsAlphaNum char rarr boolis decimal digit IsDigit char rarr boolis hexadecimal digit IsHexDigit char rarr boolis lowercase IsLower char rarr boolis uppercase IsUpper char rarr boolparse binary FromBinString string rarr num optionparse decimal FromDecString string rarr num optionparse hexadecimal FromHexString string rarr num optionconvert to lowercase ToLower string rarr stringconvert to uppercase ToUpper string rarr string

The following string operations are useful for parsing

split from the left splitl (char rarr bool) times string rarr string times stringsplit from the right splitr (char rarr bool) times string rarr string times stringsplit into fields fields (char rarr bool) times string rarr string listsplit into tokens tokens (char rarr bool) times string rarr string list

These are based on the SML functions Substringsplitl Substringsplitr Stringfieldsand Stringtokens Character predicates are declared using special syntax for example theexpression

splitl space or hexdigit and not in set a f ( 12bcab)

gives the result lsquo( 12bc ab)rsquo

26

A8 Floating-pointThe L3 language does not provide specialised types for representing floating-point numbersHowever 32-bit (single precision) and 64-bit (double precision) bit-vector values can be treatedas floating-point numbers the following IEEE compliant encoding formats are assumed

31 30 23 22 0

s e m1 8 23

63 62 52 51 0

s e m1 11 52

Here lsquosrsquo is the sign bit (set to lsquo1rsquo for negative numbers) lsquoersquo is a biased exponent value and lsquomrsquo is thesignificand The following constants and operations are available (where lsquofprsquo stands for bits(32)or bits(64) depending on the name of the operation)

rounding modes roundTiesToEvenroundTowardPositiveroundTowardNegativeroundTowardZero

ieee_rounding

flags (record) DivideByZero InvalidOpOverflow PrecisionUnderflow

ieee_flagsrarrbool

comparison values FP_LT FP_EQ FP_GT FP_UN ieee_compare

convert format FP32_ToFP64 fp32rarrfp64convert format FP64_ToFP32 ieee_roundingtimes fp64rarrfp32convert format FP64_ToFP32_ ieee_roundingtimes fp64rarr

ieee_flagstimes fp32from integer FP32|64_FromInt ieee_roundingtimes intrarrfpto integer FP32|64_ToInt ieee_roundingtimes fprarrint optionfrom string FP32|64 stringrarrfp

negative zero FP32|64_NegZero fppositive zero FP32|64_PosZero fpnegative infinity FP32|64_NegInf fppositive infinity FP32|64_PosInf fpa quiet NaN FP32|64_qNan fpa signalling NaN FP32|64_sNan fp

is integral FP32|64_IsIntegral fprarrboolis finite FP32|64_IsFinite fprarrboolis NaN FP32|64_IsNan fprarrboolis signalling NaN FP32|64_IsSignallingNan fprarrboolis normal FP32|64_IsNormal fprarrboolis sub-normal FP32|64_IsSubnormal fprarrboolis zero FP32|64_IsZero fprarrbool

27

comparison FP32|64_Compare fptimes fprarrieee_compareequality FP32|64_Equal fptimes fprarrboolless than FP32|64_LessThan fptimes fprarrboolless than or equal FP32|64_LessEqual fptimes fprarrboolgreater than FP32|64_GreaterThan fptimes fprarrboolgreater than or equal FP32|64_GreaterEqual fptimes fprarrbool

absolute FP32|64_Abs fprarrfpnegation FP32|64_Neg fprarrfpsquare root FP32|64_Sqrt ieee_roundingtimes fprarrfp(with flags) FP32|64_Sqrt_ ieee_roundingtimes fprarrieee_flagstimes fpaddition FP32|64_Add ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Add_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpsubtraction FP32|64_Sub ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Sub_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpmultiplication FP32|64_Mul ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Mul_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpfused multiply-add FP32|64_MulAdd ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulAdd_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpfused multiply-sub FP32|64_MulSub ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulSub_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpdivision FP32|64_Div ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Div_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fp

The L3 interpreter supports evaluation for 32-bit and 64-bit floating-point expressions but onlywhen running on an x86 machine that supports SSE2 extensions (Pentium 4 and later) Thefused multiply-addsub operations can only be interpreted on machines supporting the FMAextension which came in with the 4th generation (Haswell) Intel processors These restrictionsalso apply to any Standard ML code that is generated by L3

The IEEE 754 standard permits a number of different ways to flag underflow L3 predomi-nantly supports the x86 interpretation which detects underflow after rounding However whenexporting to HOL4 it is possible to choose detection before rounding which for example issuited to ARM instruction set models

A9 Miscellaneous operationsThe following operations are available

pair constructor αtimes β rarr αtimes βfirst of pair Fst αtimes β rarr αsecond of pair Snd αtimes β rarr β

casting [middot] α rarr βinitialise a map InitMap α rarr (βrarrα)

28

option constructor Some αrarrα optionoption projection ValOf α option rarr αoption test IsSome α option rarr bool

set membership in αtimesα set rarr boolset non-membership notin αtimesα set rarr boolset insertion insert αtimesα set rarrα setset union Union α settimesα set rarrα setset intersection Intersect α settimesα set rarrα setset difference Difference α settimesα set rarrα setset subset test IsSubset α settimesα set rarr boolset cardinality Cardinality α setrarr natset from a list SetOfList α list rarrα set

empty list Nil α listlist constructor Cons αtimesα list rarr α listlist head Head α list rarr αlist tail Tail α list rarr α listlist length Length α list rarr natlist concatenation α listtimesα list rarr α listlist flatten Concat α list list rarr α listlist element Element nattimesα list rarr αlist prefix Take nattimesα list rarr α listlist drop prefix Drop nattimesα list rarr α listlist pad left PadLeft αtimes nattimesα list rarr α listlist pad right PadRight αtimes nattimesα list rarr α listlist update Update αtimes nattimesα list rarr α listlist difference Remove α listtimesα list rarr α listlist intersection RemoveExcept α listtimesα list rarr α listlist without duplicates RemoveDuplicates α listrarr α listlist membership IsMember αtimesα list rarr boollist member position IndexOf αtimesα list rarr nat option

Sets are only defined over equality types see Appendix A2 The casting map is defined overcast-able types (as represented by the polymorphic type variables α and β) these are the primitivetypes (with the exception of lsquounitrsquo) and user defined enumerated types Assume lsquoEnumrsquo and lsquoEnum2rsquoare declared with

construct Enum One Two Three construct Enum2 Four Five Six Seven

The cast operations are described in Tables 1 to 7

29

Table 1 Cast to lsquoboolrsquo

From Operation Examples

bool identity lsquo[true]boolrsquo = lsquotruersquostring parse bool lsquo[true]boolrsquo = lsquotruersquo

lsquo[false]boolrsquo = lsquofalsersquootherwise undefined

nat is not zero lsquo[0n3]boolrsquo = lsquotruersquolsquo[0n0]boolrsquo = lsquofalsersquo

int is not zero lsquo[-0i1]boolrsquo = lsquotruersquolsquo[0i0]boolrsquo = lsquofalsersquo

bool list is not zero lsquo[0s11]boolrsquo = lsquotruersquolsquo[0s0]boolrsquo = lsquofalsersquo

bits(middot) is not zero lsquo[3`3]boolrsquo = lsquotruersquolsquo[0`3]boolrsquo = lsquofalsersquo

Enum is not the first element lsquo[One]boolrsquo = lsquofalsersquolsquo[Two]boolrsquo = lsquotruersquo

Table 2 Cast to lsquostringrsquo

From Operation Examples

bool name lsquo[true]stringrsquo = lsquotruersquostring identity lsquo[hello]stringrsquo = lsquohellorsquonat decimal lsquo[0n3]stringrsquo = lsquo3rsquoint signed decimal lsquo[-0i1]stringrsquo = lsquo~1rsquobool list binary lsquo[0s11]stringrsquo = lsquo11rsquobits(middot) unsigned hexadecimal lsquo[139`8]stringrsquo = lsquo8BrsquoEnum name lsquo[One]stringrsquo = lsquoOnersquo

30

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

The infix operators lsquoandrsquo and lsquoorrsquo are interpreted with short-circuit evaluation for example in theexpression lsquofalse and f()rsquo the value of lsquof()rsquo is not computed as the overall expression will alwaysevaluate to false This short-circuiting influences the side-effects that occur during expressionevaluation

There are two prefix symbols for logical negation (these are semantically identical) with lsquorsquobinding slightly tighter than lsquonotrsquo This distinction is becomes significant when working withequalities for example lsquonot a == brsquo is taken to be not(a = b) whereas lsquoa == brsquo is (nota) = b

Equality is only defined with respect to equality types represented here by the type variableα An equality type is any type built without the used of the map operator lsquo-gtrsquo

A3 NatThe type lsquonatrsquo represents the natural numbers N = 0 1 2 The following operations areavailable

logarithm (base two) Log2 nat rarr natminimum value Min nattimes nat rarr natmaximium value Max nattimes nat rarr natless than lt nattimes nat rarr boolgreater than gt nattimes nat rarr boolless than or equal to lt= nattimes nat rarr boolgreater than or equal to gt= nattimes nat rarr booladdition + nattimes nat rarr natsubtraction - nattimes nat rarr natmultiplication nattimes nat rarr natexponentiation nattimes nat rarr natdivision div nattimes nat rarr natmodulus mod nattimes nat rarr nat

The lsquodivrsquo and lsquomodrsquo operations satisfy the following property

foralln 0 lt n =rArr forallk k = (k div n) lowast n+ (k mod n) and (k mod n) lt n

The expressions lsquoLog2(0)rsquo lsquox div 0rsquo and lsquox mod 0rsquo are all undefined 17

A4 IntThe type lsquointrsquo represents the integers Z = Ncupminus1minus2minus3 The following operations areavailable

17The interpreter will raise an exception when attempting to evaluate them

22

unary minus - int rarr intabsolute value Abs int rarr intminimum value Min inttimes int rarr intmaximum value Max inttimes int rarr intless than lt inttimes int rarr boolgreater than gt inttimes int rarr boolless than or equal to lt= inttimes int rarr boolgreater than or equal to gt= inttimes int rarr booladdition + inttimes int rarr intsubtraction - inttimes int rarr intmultiplication inttimes int rarr intexponentiation inttimes nat rarr intquotient and remainder QuotRem inttimes int rarr inttimes intquotient quot inttimes int rarr intremainder rem inttimes int rarr intdivision div inttimes int rarr intmodulus mod inttimes int rarr int

The operation lsquoAbsrsquo gives an positive integer value for example lsquoAbs(-2)rsquo = lsquo2rsquo The integeroperations lsquoquotrsquo and lsquodivrsquo are related to natural number division as follows

i quot j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

and

i div j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(minusi) div n(j))minus 1 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i and n(i) mod n(minusj) = 0

minus z(n(i) div n(minusj))minus 1 j lt 0 and 0 le i and n(i) mod n(minusj) = 0

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

where z NrarrZ and n ZrarrN are value preserving maps The lsquoremrsquo and lsquomodrsquo operations satisfythe equations

i rem j =

iminus (i quot j) lowast j j = 0

undefined j = 0i mod j =

iminus (i div j) lowast j j = 0

undefined j = 0

A5 Bit-vectorsThe type lsquobits(n)rsquo represents fixed-width (n-bit) words also known as bit-vectors for examplebits(32) is the type of 32-bit machine words18 The bits type can be viewed as representing

18These are called double-words (dword) in the x86 architecture and simply words in the ARM architecture

23

the set Zn = 0 1 2nminus1 for some 0 lt n At the type system level no distinction is madebetween signed and unsigned words however some operations (such as orderings) have signedand unsigned variants

The following bit-vector operations are available

1rsquos complement ~ bits(n) rarr bits(n)2rsquos complement - bits(n) rarr bits(n)absolute value Abs bits(n) rarr bits(n)logarithm (base two) Log2 bits(n) rarr bits(n)zero-extend ZeroExtend bits(m) rarr bits(n)sign-extend SignExtend bits(m) rarr bits(n)reverse bits Reverse bits(n) rarr bits(n)minimum value (u) Min bits(n)times bits(n) rarr bits(n)maximum value (u) Max bits(n)times bits(n) rarr bits(n)minimum value (s) SignedMin bits(n)times bits(n) rarr bits(n)maximum value (s) SignedMax bits(n)times bits(n) rarr bits(n)widthsize Size bits(n) rarr natmost-significant (sign) bit Msb bits(n) rarr boolbit value middot ltmiddotgt bits(n)times nat rarr boolbit field middot ltmiddotmiddotgt bits(m)times nattimes nat rarr bits(n)concatenation bits(m)times bits(n) rarr bits(p)duplication ^ bits(m)times nat rarr bits(n)less than (s) lt bits(n)times bits(n) rarr boolgreater than (s) gt bits(n)times bits(n) rarr boolless than or equal to (s) lt= bits(n)times bits(n) rarr boolgreater than or equal to (s) gt= bits(n)times bits(n) rarr boolless than (u) lt+ bits(n)times bits(n) rarr boolgreater than (u) gt+ bits(n)times bits(n) rarr boolless than or equal to (u) lt=+ bits(n)times bits(n) rarr boolgreater than or equal to (u) gt=+ bits(n)times bits(n) rarr booladdition + bits(n)times bits(n) rarr bits(n)subtraction - bits(n)times bits(n) rarr bits(n)multiplication bits(n)times bits(n) rarr bits(n)quotient (s) quot bits(n)times bits(n) rarr bits(n)remained (s) rem bits(n)times bits(n) rarr bits(n)division (u) div bits(n)times bits(n) rarr bits(n)modulus (u) mod bits(n)times bits(n) rarr bits(n)division (s) sdiv bits(n)times bits(n) rarr bits(n)modulus (s) smod bits(n)times bits(n) rarr bits(n)bitwise conjunction ampamp bits(n)times bits(n) rarr bits(n)bitwise disjunction || bits(n)times bits(n) rarr bits(n)bitwise exclusive-or bits(n)times bits(n) rarr bits(n)

Unsigned operations are labelled with (u) and signed operations are labelled with (s)The shift operations support shifting by either a bit-vector value or by a natural number value

The overloading is resolved such that the lsquonatrsquo variant is selected over the lsquobits(middot)rsquo version Theshift operations are

24

left-shift ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (u) gtgt+ bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (s) gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate left ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate right gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

A number of operations are undefined depending on the types of their domain and rangeThis is detailed in the following table

Operation Undefined when

ZeroExtend(x`n)`m m lt nSignExtend(x`n)`m m lt n(x`m)ltpgt m le p(x`m)lthlgt`n n = h+ 1minus l or h lt l orm le h((xm) (yn))`p p = m+ n((x`m) ^ n)`p p = m middot n (which covers n = 0)

The type checker will fail when these conditions are obviously violated Alternatively the inter-preter may raise a runtime error when these conditions are not met

As before the expressions lsquoLog2(0)rsquo lsquox quot 0rsquo lsquox rem 0rsquo lsquox div 0rsquo and lsquox mod 0rsquo are allundefined

A6 Bit-stringsVarious bit-string operation are defined over the type lsquobool listrsquo These are listed below

bit value middot ltmiddotgt bool listtimes nat rarr boolbit field middot ltmiddotmiddotgt bool listtimes nattimes nat rarr bool listconcatenation bool listtimes bool list rarr bool listduplication ^ bool listtimes nat rarr bool listaddition + bool listtimes bool list rarr bool listbitwise conjunction ampamp bool listtimes bool list rarr bool listbitwise disjunction || bool listtimes bool list rarr bool listbitwise exclusive-or bool listtimes bool list rarr bool listleft-shift ltlt bool listtimes nat rarr bool listright-shift gtgt+ bool listtimes nat rarr bool listrotate-right gtgt bool listtimes nat rarr bool list

The bit value operation gives the truth value of a bit-string at a given bit position for example

lsquo0s1101lt0gtrsquo = lsquotruersquo lsquo0s1101lt1gtrsquo = lsquofalsersquo lsquo0s1101lt2gtrsquo = lsquotruersquolsquo0s1101lt3gtrsquo = lsquotruersquo lsquo0s1101lt4gtrsquo = lsquofalsersquo lsquo0s1101lt5gtrsquo = lsquofalsersquo

25

The least-significant bit (position zero) occurs to the right of the bit-string The bit value oper-ation gives lsquofalsersquo when the bit position is greater than the size of the bit-string

The bit field operation extracts a range of bits from a bit-string For example

lsquo0s1101lt31gtrsquo = lsquo0s110rsquo and lsquo0s1101lt52gtrsquo = lsquo0s0011rsquo

In the bit-string expression xlthlgt the size of the result is always h + 1 minus l and the result isundefined when h lt l

Bit-string addition does not require the arguments to be of the same size and it gives anon-truncated result For example

lsquo0s101 + 0s1rsquo = lsquo0s110rsquo and lsquo0s101 + 0s11rsquo = lsquo0s1000rsquo

The operation ltlt performs a left-shift for example lsquo0s1101 ltlt 2rsquo = lsquo0s110100rsquo The oper-ation lsquorsquo is bit-string concatenation and lsquo^rsquo is duplication for example

lsquo0s101 0s11rsquo = lsquo0s10111rsquo and lsquo0s101 ^ 3rsquo = lsquo0s101101101rsquo

Regular list operations work as one would expect over bit-strings for example lsquoHead (0s101)rsquois a valid expression with value lsquotruersquo

A7 Characters and StringsThe following built-in functions are available for characters and strings

is alphabetic IsAlpha char rarr boolis alpha-numeric IsAlphaNum char rarr boolis decimal digit IsDigit char rarr boolis hexadecimal digit IsHexDigit char rarr boolis lowercase IsLower char rarr boolis uppercase IsUpper char rarr boolparse binary FromBinString string rarr num optionparse decimal FromDecString string rarr num optionparse hexadecimal FromHexString string rarr num optionconvert to lowercase ToLower string rarr stringconvert to uppercase ToUpper string rarr string

The following string operations are useful for parsing

split from the left splitl (char rarr bool) times string rarr string times stringsplit from the right splitr (char rarr bool) times string rarr string times stringsplit into fields fields (char rarr bool) times string rarr string listsplit into tokens tokens (char rarr bool) times string rarr string list

These are based on the SML functions Substringsplitl Substringsplitr Stringfieldsand Stringtokens Character predicates are declared using special syntax for example theexpression

splitl space or hexdigit and not in set a f ( 12bcab)

gives the result lsquo( 12bc ab)rsquo

26

A8 Floating-pointThe L3 language does not provide specialised types for representing floating-point numbersHowever 32-bit (single precision) and 64-bit (double precision) bit-vector values can be treatedas floating-point numbers the following IEEE compliant encoding formats are assumed

31 30 23 22 0

s e m1 8 23

63 62 52 51 0

s e m1 11 52

Here lsquosrsquo is the sign bit (set to lsquo1rsquo for negative numbers) lsquoersquo is a biased exponent value and lsquomrsquo is thesignificand The following constants and operations are available (where lsquofprsquo stands for bits(32)or bits(64) depending on the name of the operation)

rounding modes roundTiesToEvenroundTowardPositiveroundTowardNegativeroundTowardZero

ieee_rounding

flags (record) DivideByZero InvalidOpOverflow PrecisionUnderflow

ieee_flagsrarrbool

comparison values FP_LT FP_EQ FP_GT FP_UN ieee_compare

convert format FP32_ToFP64 fp32rarrfp64convert format FP64_ToFP32 ieee_roundingtimes fp64rarrfp32convert format FP64_ToFP32_ ieee_roundingtimes fp64rarr

ieee_flagstimes fp32from integer FP32|64_FromInt ieee_roundingtimes intrarrfpto integer FP32|64_ToInt ieee_roundingtimes fprarrint optionfrom string FP32|64 stringrarrfp

negative zero FP32|64_NegZero fppositive zero FP32|64_PosZero fpnegative infinity FP32|64_NegInf fppositive infinity FP32|64_PosInf fpa quiet NaN FP32|64_qNan fpa signalling NaN FP32|64_sNan fp

is integral FP32|64_IsIntegral fprarrboolis finite FP32|64_IsFinite fprarrboolis NaN FP32|64_IsNan fprarrboolis signalling NaN FP32|64_IsSignallingNan fprarrboolis normal FP32|64_IsNormal fprarrboolis sub-normal FP32|64_IsSubnormal fprarrboolis zero FP32|64_IsZero fprarrbool

27

comparison FP32|64_Compare fptimes fprarrieee_compareequality FP32|64_Equal fptimes fprarrboolless than FP32|64_LessThan fptimes fprarrboolless than or equal FP32|64_LessEqual fptimes fprarrboolgreater than FP32|64_GreaterThan fptimes fprarrboolgreater than or equal FP32|64_GreaterEqual fptimes fprarrbool

absolute FP32|64_Abs fprarrfpnegation FP32|64_Neg fprarrfpsquare root FP32|64_Sqrt ieee_roundingtimes fprarrfp(with flags) FP32|64_Sqrt_ ieee_roundingtimes fprarrieee_flagstimes fpaddition FP32|64_Add ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Add_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpsubtraction FP32|64_Sub ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Sub_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpmultiplication FP32|64_Mul ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Mul_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpfused multiply-add FP32|64_MulAdd ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulAdd_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpfused multiply-sub FP32|64_MulSub ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulSub_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpdivision FP32|64_Div ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Div_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fp

The L3 interpreter supports evaluation for 32-bit and 64-bit floating-point expressions but onlywhen running on an x86 machine that supports SSE2 extensions (Pentium 4 and later) Thefused multiply-addsub operations can only be interpreted on machines supporting the FMAextension which came in with the 4th generation (Haswell) Intel processors These restrictionsalso apply to any Standard ML code that is generated by L3

The IEEE 754 standard permits a number of different ways to flag underflow L3 predomi-nantly supports the x86 interpretation which detects underflow after rounding However whenexporting to HOL4 it is possible to choose detection before rounding which for example issuited to ARM instruction set models

A9 Miscellaneous operationsThe following operations are available

pair constructor αtimes β rarr αtimes βfirst of pair Fst αtimes β rarr αsecond of pair Snd αtimes β rarr β

casting [middot] α rarr βinitialise a map InitMap α rarr (βrarrα)

28

option constructor Some αrarrα optionoption projection ValOf α option rarr αoption test IsSome α option rarr bool

set membership in αtimesα set rarr boolset non-membership notin αtimesα set rarr boolset insertion insert αtimesα set rarrα setset union Union α settimesα set rarrα setset intersection Intersect α settimesα set rarrα setset difference Difference α settimesα set rarrα setset subset test IsSubset α settimesα set rarr boolset cardinality Cardinality α setrarr natset from a list SetOfList α list rarrα set

empty list Nil α listlist constructor Cons αtimesα list rarr α listlist head Head α list rarr αlist tail Tail α list rarr α listlist length Length α list rarr natlist concatenation α listtimesα list rarr α listlist flatten Concat α list list rarr α listlist element Element nattimesα list rarr αlist prefix Take nattimesα list rarr α listlist drop prefix Drop nattimesα list rarr α listlist pad left PadLeft αtimes nattimesα list rarr α listlist pad right PadRight αtimes nattimesα list rarr α listlist update Update αtimes nattimesα list rarr α listlist difference Remove α listtimesα list rarr α listlist intersection RemoveExcept α listtimesα list rarr α listlist without duplicates RemoveDuplicates α listrarr α listlist membership IsMember αtimesα list rarr boollist member position IndexOf αtimesα list rarr nat option

Sets are only defined over equality types see Appendix A2 The casting map is defined overcast-able types (as represented by the polymorphic type variables α and β) these are the primitivetypes (with the exception of lsquounitrsquo) and user defined enumerated types Assume lsquoEnumrsquo and lsquoEnum2rsquoare declared with

construct Enum One Two Three construct Enum2 Four Five Six Seven

The cast operations are described in Tables 1 to 7

29

Table 1 Cast to lsquoboolrsquo

From Operation Examples

bool identity lsquo[true]boolrsquo = lsquotruersquostring parse bool lsquo[true]boolrsquo = lsquotruersquo

lsquo[false]boolrsquo = lsquofalsersquootherwise undefined

nat is not zero lsquo[0n3]boolrsquo = lsquotruersquolsquo[0n0]boolrsquo = lsquofalsersquo

int is not zero lsquo[-0i1]boolrsquo = lsquotruersquolsquo[0i0]boolrsquo = lsquofalsersquo

bool list is not zero lsquo[0s11]boolrsquo = lsquotruersquolsquo[0s0]boolrsquo = lsquofalsersquo

bits(middot) is not zero lsquo[3`3]boolrsquo = lsquotruersquolsquo[0`3]boolrsquo = lsquofalsersquo

Enum is not the first element lsquo[One]boolrsquo = lsquofalsersquolsquo[Two]boolrsquo = lsquotruersquo

Table 2 Cast to lsquostringrsquo

From Operation Examples

bool name lsquo[true]stringrsquo = lsquotruersquostring identity lsquo[hello]stringrsquo = lsquohellorsquonat decimal lsquo[0n3]stringrsquo = lsquo3rsquoint signed decimal lsquo[-0i1]stringrsquo = lsquo~1rsquobool list binary lsquo[0s11]stringrsquo = lsquo11rsquobits(middot) unsigned hexadecimal lsquo[139`8]stringrsquo = lsquo8BrsquoEnum name lsquo[One]stringrsquo = lsquoOnersquo

30

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

unary minus - int rarr intabsolute value Abs int rarr intminimum value Min inttimes int rarr intmaximum value Max inttimes int rarr intless than lt inttimes int rarr boolgreater than gt inttimes int rarr boolless than or equal to lt= inttimes int rarr boolgreater than or equal to gt= inttimes int rarr booladdition + inttimes int rarr intsubtraction - inttimes int rarr intmultiplication inttimes int rarr intexponentiation inttimes nat rarr intquotient and remainder QuotRem inttimes int rarr inttimes intquotient quot inttimes int rarr intremainder rem inttimes int rarr intdivision div inttimes int rarr intmodulus mod inttimes int rarr int

The operation lsquoAbsrsquo gives an positive integer value for example lsquoAbs(-2)rsquo = lsquo2rsquo The integeroperations lsquoquotrsquo and lsquodivrsquo are related to natural number division as follows

i quot j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

and

i div j =

z(n(i) div n(j)) 0 lt j and 0 le i

minus z(n(minusi) div n(j)) 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(minusi) div n(j))minus 1 0 lt j and i lt 0 and n(minusi) mod n(j) = 0

minus z(n(i) div n(minusj)) j lt 0 and 0 le i and n(i) mod n(minusj) = 0

minus z(n(i) div n(minusj))minus 1 j lt 0 and 0 le i and n(i) mod n(minusj) = 0

z(n(minusi) div n(minusj)) j lt 0 and i lt 0

undefined j = 0

where z NrarrZ and n ZrarrN are value preserving maps The lsquoremrsquo and lsquomodrsquo operations satisfythe equations

i rem j =

iminus (i quot j) lowast j j = 0

undefined j = 0i mod j =

iminus (i div j) lowast j j = 0

undefined j = 0

A5 Bit-vectorsThe type lsquobits(n)rsquo represents fixed-width (n-bit) words also known as bit-vectors for examplebits(32) is the type of 32-bit machine words18 The bits type can be viewed as representing

18These are called double-words (dword) in the x86 architecture and simply words in the ARM architecture

23

the set Zn = 0 1 2nminus1 for some 0 lt n At the type system level no distinction is madebetween signed and unsigned words however some operations (such as orderings) have signedand unsigned variants

The following bit-vector operations are available

1rsquos complement ~ bits(n) rarr bits(n)2rsquos complement - bits(n) rarr bits(n)absolute value Abs bits(n) rarr bits(n)logarithm (base two) Log2 bits(n) rarr bits(n)zero-extend ZeroExtend bits(m) rarr bits(n)sign-extend SignExtend bits(m) rarr bits(n)reverse bits Reverse bits(n) rarr bits(n)minimum value (u) Min bits(n)times bits(n) rarr bits(n)maximum value (u) Max bits(n)times bits(n) rarr bits(n)minimum value (s) SignedMin bits(n)times bits(n) rarr bits(n)maximum value (s) SignedMax bits(n)times bits(n) rarr bits(n)widthsize Size bits(n) rarr natmost-significant (sign) bit Msb bits(n) rarr boolbit value middot ltmiddotgt bits(n)times nat rarr boolbit field middot ltmiddotmiddotgt bits(m)times nattimes nat rarr bits(n)concatenation bits(m)times bits(n) rarr bits(p)duplication ^ bits(m)times nat rarr bits(n)less than (s) lt bits(n)times bits(n) rarr boolgreater than (s) gt bits(n)times bits(n) rarr boolless than or equal to (s) lt= bits(n)times bits(n) rarr boolgreater than or equal to (s) gt= bits(n)times bits(n) rarr boolless than (u) lt+ bits(n)times bits(n) rarr boolgreater than (u) gt+ bits(n)times bits(n) rarr boolless than or equal to (u) lt=+ bits(n)times bits(n) rarr boolgreater than or equal to (u) gt=+ bits(n)times bits(n) rarr booladdition + bits(n)times bits(n) rarr bits(n)subtraction - bits(n)times bits(n) rarr bits(n)multiplication bits(n)times bits(n) rarr bits(n)quotient (s) quot bits(n)times bits(n) rarr bits(n)remained (s) rem bits(n)times bits(n) rarr bits(n)division (u) div bits(n)times bits(n) rarr bits(n)modulus (u) mod bits(n)times bits(n) rarr bits(n)division (s) sdiv bits(n)times bits(n) rarr bits(n)modulus (s) smod bits(n)times bits(n) rarr bits(n)bitwise conjunction ampamp bits(n)times bits(n) rarr bits(n)bitwise disjunction || bits(n)times bits(n) rarr bits(n)bitwise exclusive-or bits(n)times bits(n) rarr bits(n)

Unsigned operations are labelled with (u) and signed operations are labelled with (s)The shift operations support shifting by either a bit-vector value or by a natural number value

The overloading is resolved such that the lsquonatrsquo variant is selected over the lsquobits(middot)rsquo version Theshift operations are

24

left-shift ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (u) gtgt+ bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (s) gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate left ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate right gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

A number of operations are undefined depending on the types of their domain and rangeThis is detailed in the following table

Operation Undefined when

ZeroExtend(x`n)`m m lt nSignExtend(x`n)`m m lt n(x`m)ltpgt m le p(x`m)lthlgt`n n = h+ 1minus l or h lt l orm le h((xm) (yn))`p p = m+ n((x`m) ^ n)`p p = m middot n (which covers n = 0)

The type checker will fail when these conditions are obviously violated Alternatively the inter-preter may raise a runtime error when these conditions are not met

As before the expressions lsquoLog2(0)rsquo lsquox quot 0rsquo lsquox rem 0rsquo lsquox div 0rsquo and lsquox mod 0rsquo are allundefined

A6 Bit-stringsVarious bit-string operation are defined over the type lsquobool listrsquo These are listed below

bit value middot ltmiddotgt bool listtimes nat rarr boolbit field middot ltmiddotmiddotgt bool listtimes nattimes nat rarr bool listconcatenation bool listtimes bool list rarr bool listduplication ^ bool listtimes nat rarr bool listaddition + bool listtimes bool list rarr bool listbitwise conjunction ampamp bool listtimes bool list rarr bool listbitwise disjunction || bool listtimes bool list rarr bool listbitwise exclusive-or bool listtimes bool list rarr bool listleft-shift ltlt bool listtimes nat rarr bool listright-shift gtgt+ bool listtimes nat rarr bool listrotate-right gtgt bool listtimes nat rarr bool list

The bit value operation gives the truth value of a bit-string at a given bit position for example

lsquo0s1101lt0gtrsquo = lsquotruersquo lsquo0s1101lt1gtrsquo = lsquofalsersquo lsquo0s1101lt2gtrsquo = lsquotruersquolsquo0s1101lt3gtrsquo = lsquotruersquo lsquo0s1101lt4gtrsquo = lsquofalsersquo lsquo0s1101lt5gtrsquo = lsquofalsersquo

25

The least-significant bit (position zero) occurs to the right of the bit-string The bit value oper-ation gives lsquofalsersquo when the bit position is greater than the size of the bit-string

The bit field operation extracts a range of bits from a bit-string For example

lsquo0s1101lt31gtrsquo = lsquo0s110rsquo and lsquo0s1101lt52gtrsquo = lsquo0s0011rsquo

In the bit-string expression xlthlgt the size of the result is always h + 1 minus l and the result isundefined when h lt l

Bit-string addition does not require the arguments to be of the same size and it gives anon-truncated result For example

lsquo0s101 + 0s1rsquo = lsquo0s110rsquo and lsquo0s101 + 0s11rsquo = lsquo0s1000rsquo

The operation ltlt performs a left-shift for example lsquo0s1101 ltlt 2rsquo = lsquo0s110100rsquo The oper-ation lsquorsquo is bit-string concatenation and lsquo^rsquo is duplication for example

lsquo0s101 0s11rsquo = lsquo0s10111rsquo and lsquo0s101 ^ 3rsquo = lsquo0s101101101rsquo

Regular list operations work as one would expect over bit-strings for example lsquoHead (0s101)rsquois a valid expression with value lsquotruersquo

A7 Characters and StringsThe following built-in functions are available for characters and strings

is alphabetic IsAlpha char rarr boolis alpha-numeric IsAlphaNum char rarr boolis decimal digit IsDigit char rarr boolis hexadecimal digit IsHexDigit char rarr boolis lowercase IsLower char rarr boolis uppercase IsUpper char rarr boolparse binary FromBinString string rarr num optionparse decimal FromDecString string rarr num optionparse hexadecimal FromHexString string rarr num optionconvert to lowercase ToLower string rarr stringconvert to uppercase ToUpper string rarr string

The following string operations are useful for parsing

split from the left splitl (char rarr bool) times string rarr string times stringsplit from the right splitr (char rarr bool) times string rarr string times stringsplit into fields fields (char rarr bool) times string rarr string listsplit into tokens tokens (char rarr bool) times string rarr string list

These are based on the SML functions Substringsplitl Substringsplitr Stringfieldsand Stringtokens Character predicates are declared using special syntax for example theexpression

splitl space or hexdigit and not in set a f ( 12bcab)

gives the result lsquo( 12bc ab)rsquo

26

A8 Floating-pointThe L3 language does not provide specialised types for representing floating-point numbersHowever 32-bit (single precision) and 64-bit (double precision) bit-vector values can be treatedas floating-point numbers the following IEEE compliant encoding formats are assumed

31 30 23 22 0

s e m1 8 23

63 62 52 51 0

s e m1 11 52

Here lsquosrsquo is the sign bit (set to lsquo1rsquo for negative numbers) lsquoersquo is a biased exponent value and lsquomrsquo is thesignificand The following constants and operations are available (where lsquofprsquo stands for bits(32)or bits(64) depending on the name of the operation)

rounding modes roundTiesToEvenroundTowardPositiveroundTowardNegativeroundTowardZero

ieee_rounding

flags (record) DivideByZero InvalidOpOverflow PrecisionUnderflow

ieee_flagsrarrbool

comparison values FP_LT FP_EQ FP_GT FP_UN ieee_compare

convert format FP32_ToFP64 fp32rarrfp64convert format FP64_ToFP32 ieee_roundingtimes fp64rarrfp32convert format FP64_ToFP32_ ieee_roundingtimes fp64rarr

ieee_flagstimes fp32from integer FP32|64_FromInt ieee_roundingtimes intrarrfpto integer FP32|64_ToInt ieee_roundingtimes fprarrint optionfrom string FP32|64 stringrarrfp

negative zero FP32|64_NegZero fppositive zero FP32|64_PosZero fpnegative infinity FP32|64_NegInf fppositive infinity FP32|64_PosInf fpa quiet NaN FP32|64_qNan fpa signalling NaN FP32|64_sNan fp

is integral FP32|64_IsIntegral fprarrboolis finite FP32|64_IsFinite fprarrboolis NaN FP32|64_IsNan fprarrboolis signalling NaN FP32|64_IsSignallingNan fprarrboolis normal FP32|64_IsNormal fprarrboolis sub-normal FP32|64_IsSubnormal fprarrboolis zero FP32|64_IsZero fprarrbool

27

comparison FP32|64_Compare fptimes fprarrieee_compareequality FP32|64_Equal fptimes fprarrboolless than FP32|64_LessThan fptimes fprarrboolless than or equal FP32|64_LessEqual fptimes fprarrboolgreater than FP32|64_GreaterThan fptimes fprarrboolgreater than or equal FP32|64_GreaterEqual fptimes fprarrbool

absolute FP32|64_Abs fprarrfpnegation FP32|64_Neg fprarrfpsquare root FP32|64_Sqrt ieee_roundingtimes fprarrfp(with flags) FP32|64_Sqrt_ ieee_roundingtimes fprarrieee_flagstimes fpaddition FP32|64_Add ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Add_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpsubtraction FP32|64_Sub ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Sub_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpmultiplication FP32|64_Mul ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Mul_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpfused multiply-add FP32|64_MulAdd ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulAdd_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpfused multiply-sub FP32|64_MulSub ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulSub_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpdivision FP32|64_Div ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Div_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fp

The L3 interpreter supports evaluation for 32-bit and 64-bit floating-point expressions but onlywhen running on an x86 machine that supports SSE2 extensions (Pentium 4 and later) Thefused multiply-addsub operations can only be interpreted on machines supporting the FMAextension which came in with the 4th generation (Haswell) Intel processors These restrictionsalso apply to any Standard ML code that is generated by L3

The IEEE 754 standard permits a number of different ways to flag underflow L3 predomi-nantly supports the x86 interpretation which detects underflow after rounding However whenexporting to HOL4 it is possible to choose detection before rounding which for example issuited to ARM instruction set models

A9 Miscellaneous operationsThe following operations are available

pair constructor αtimes β rarr αtimes βfirst of pair Fst αtimes β rarr αsecond of pair Snd αtimes β rarr β

casting [middot] α rarr βinitialise a map InitMap α rarr (βrarrα)

28

option constructor Some αrarrα optionoption projection ValOf α option rarr αoption test IsSome α option rarr bool

set membership in αtimesα set rarr boolset non-membership notin αtimesα set rarr boolset insertion insert αtimesα set rarrα setset union Union α settimesα set rarrα setset intersection Intersect α settimesα set rarrα setset difference Difference α settimesα set rarrα setset subset test IsSubset α settimesα set rarr boolset cardinality Cardinality α setrarr natset from a list SetOfList α list rarrα set

empty list Nil α listlist constructor Cons αtimesα list rarr α listlist head Head α list rarr αlist tail Tail α list rarr α listlist length Length α list rarr natlist concatenation α listtimesα list rarr α listlist flatten Concat α list list rarr α listlist element Element nattimesα list rarr αlist prefix Take nattimesα list rarr α listlist drop prefix Drop nattimesα list rarr α listlist pad left PadLeft αtimes nattimesα list rarr α listlist pad right PadRight αtimes nattimesα list rarr α listlist update Update αtimes nattimesα list rarr α listlist difference Remove α listtimesα list rarr α listlist intersection RemoveExcept α listtimesα list rarr α listlist without duplicates RemoveDuplicates α listrarr α listlist membership IsMember αtimesα list rarr boollist member position IndexOf αtimesα list rarr nat option

Sets are only defined over equality types see Appendix A2 The casting map is defined overcast-able types (as represented by the polymorphic type variables α and β) these are the primitivetypes (with the exception of lsquounitrsquo) and user defined enumerated types Assume lsquoEnumrsquo and lsquoEnum2rsquoare declared with

construct Enum One Two Three construct Enum2 Four Five Six Seven

The cast operations are described in Tables 1 to 7

29

Table 1 Cast to lsquoboolrsquo

From Operation Examples

bool identity lsquo[true]boolrsquo = lsquotruersquostring parse bool lsquo[true]boolrsquo = lsquotruersquo

lsquo[false]boolrsquo = lsquofalsersquootherwise undefined

nat is not zero lsquo[0n3]boolrsquo = lsquotruersquolsquo[0n0]boolrsquo = lsquofalsersquo

int is not zero lsquo[-0i1]boolrsquo = lsquotruersquolsquo[0i0]boolrsquo = lsquofalsersquo

bool list is not zero lsquo[0s11]boolrsquo = lsquotruersquolsquo[0s0]boolrsquo = lsquofalsersquo

bits(middot) is not zero lsquo[3`3]boolrsquo = lsquotruersquolsquo[0`3]boolrsquo = lsquofalsersquo

Enum is not the first element lsquo[One]boolrsquo = lsquofalsersquolsquo[Two]boolrsquo = lsquotruersquo

Table 2 Cast to lsquostringrsquo

From Operation Examples

bool name lsquo[true]stringrsquo = lsquotruersquostring identity lsquo[hello]stringrsquo = lsquohellorsquonat decimal lsquo[0n3]stringrsquo = lsquo3rsquoint signed decimal lsquo[-0i1]stringrsquo = lsquo~1rsquobool list binary lsquo[0s11]stringrsquo = lsquo11rsquobits(middot) unsigned hexadecimal lsquo[139`8]stringrsquo = lsquo8BrsquoEnum name lsquo[One]stringrsquo = lsquoOnersquo

30

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

the set Zn = 0 1 2nminus1 for some 0 lt n At the type system level no distinction is madebetween signed and unsigned words however some operations (such as orderings) have signedand unsigned variants

The following bit-vector operations are available

1rsquos complement ~ bits(n) rarr bits(n)2rsquos complement - bits(n) rarr bits(n)absolute value Abs bits(n) rarr bits(n)logarithm (base two) Log2 bits(n) rarr bits(n)zero-extend ZeroExtend bits(m) rarr bits(n)sign-extend SignExtend bits(m) rarr bits(n)reverse bits Reverse bits(n) rarr bits(n)minimum value (u) Min bits(n)times bits(n) rarr bits(n)maximum value (u) Max bits(n)times bits(n) rarr bits(n)minimum value (s) SignedMin bits(n)times bits(n) rarr bits(n)maximum value (s) SignedMax bits(n)times bits(n) rarr bits(n)widthsize Size bits(n) rarr natmost-significant (sign) bit Msb bits(n) rarr boolbit value middot ltmiddotgt bits(n)times nat rarr boolbit field middot ltmiddotmiddotgt bits(m)times nattimes nat rarr bits(n)concatenation bits(m)times bits(n) rarr bits(p)duplication ^ bits(m)times nat rarr bits(n)less than (s) lt bits(n)times bits(n) rarr boolgreater than (s) gt bits(n)times bits(n) rarr boolless than or equal to (s) lt= bits(n)times bits(n) rarr boolgreater than or equal to (s) gt= bits(n)times bits(n) rarr boolless than (u) lt+ bits(n)times bits(n) rarr boolgreater than (u) gt+ bits(n)times bits(n) rarr boolless than or equal to (u) lt=+ bits(n)times bits(n) rarr boolgreater than or equal to (u) gt=+ bits(n)times bits(n) rarr booladdition + bits(n)times bits(n) rarr bits(n)subtraction - bits(n)times bits(n) rarr bits(n)multiplication bits(n)times bits(n) rarr bits(n)quotient (s) quot bits(n)times bits(n) rarr bits(n)remained (s) rem bits(n)times bits(n) rarr bits(n)division (u) div bits(n)times bits(n) rarr bits(n)modulus (u) mod bits(n)times bits(n) rarr bits(n)division (s) sdiv bits(n)times bits(n) rarr bits(n)modulus (s) smod bits(n)times bits(n) rarr bits(n)bitwise conjunction ampamp bits(n)times bits(n) rarr bits(n)bitwise disjunction || bits(n)times bits(n) rarr bits(n)bitwise exclusive-or bits(n)times bits(n) rarr bits(n)

Unsigned operations are labelled with (u) and signed operations are labelled with (s)The shift operations support shifting by either a bit-vector value or by a natural number value

The overloading is resolved such that the lsquonatrsquo variant is selected over the lsquobits(middot)rsquo version Theshift operations are

24

left-shift ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (u) gtgt+ bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (s) gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate left ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate right gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

A number of operations are undefined depending on the types of their domain and rangeThis is detailed in the following table

Operation Undefined when

ZeroExtend(x`n)`m m lt nSignExtend(x`n)`m m lt n(x`m)ltpgt m le p(x`m)lthlgt`n n = h+ 1minus l or h lt l orm le h((xm) (yn))`p p = m+ n((x`m) ^ n)`p p = m middot n (which covers n = 0)

The type checker will fail when these conditions are obviously violated Alternatively the inter-preter may raise a runtime error when these conditions are not met

As before the expressions lsquoLog2(0)rsquo lsquox quot 0rsquo lsquox rem 0rsquo lsquox div 0rsquo and lsquox mod 0rsquo are allundefined

A6 Bit-stringsVarious bit-string operation are defined over the type lsquobool listrsquo These are listed below

bit value middot ltmiddotgt bool listtimes nat rarr boolbit field middot ltmiddotmiddotgt bool listtimes nattimes nat rarr bool listconcatenation bool listtimes bool list rarr bool listduplication ^ bool listtimes nat rarr bool listaddition + bool listtimes bool list rarr bool listbitwise conjunction ampamp bool listtimes bool list rarr bool listbitwise disjunction || bool listtimes bool list rarr bool listbitwise exclusive-or bool listtimes bool list rarr bool listleft-shift ltlt bool listtimes nat rarr bool listright-shift gtgt+ bool listtimes nat rarr bool listrotate-right gtgt bool listtimes nat rarr bool list

The bit value operation gives the truth value of a bit-string at a given bit position for example

lsquo0s1101lt0gtrsquo = lsquotruersquo lsquo0s1101lt1gtrsquo = lsquofalsersquo lsquo0s1101lt2gtrsquo = lsquotruersquolsquo0s1101lt3gtrsquo = lsquotruersquo lsquo0s1101lt4gtrsquo = lsquofalsersquo lsquo0s1101lt5gtrsquo = lsquofalsersquo

25

The least-significant bit (position zero) occurs to the right of the bit-string The bit value oper-ation gives lsquofalsersquo when the bit position is greater than the size of the bit-string

The bit field operation extracts a range of bits from a bit-string For example

lsquo0s1101lt31gtrsquo = lsquo0s110rsquo and lsquo0s1101lt52gtrsquo = lsquo0s0011rsquo

In the bit-string expression xlthlgt the size of the result is always h + 1 minus l and the result isundefined when h lt l

Bit-string addition does not require the arguments to be of the same size and it gives anon-truncated result For example

lsquo0s101 + 0s1rsquo = lsquo0s110rsquo and lsquo0s101 + 0s11rsquo = lsquo0s1000rsquo

The operation ltlt performs a left-shift for example lsquo0s1101 ltlt 2rsquo = lsquo0s110100rsquo The oper-ation lsquorsquo is bit-string concatenation and lsquo^rsquo is duplication for example

lsquo0s101 0s11rsquo = lsquo0s10111rsquo and lsquo0s101 ^ 3rsquo = lsquo0s101101101rsquo

Regular list operations work as one would expect over bit-strings for example lsquoHead (0s101)rsquois a valid expression with value lsquotruersquo

A7 Characters and StringsThe following built-in functions are available for characters and strings

is alphabetic IsAlpha char rarr boolis alpha-numeric IsAlphaNum char rarr boolis decimal digit IsDigit char rarr boolis hexadecimal digit IsHexDigit char rarr boolis lowercase IsLower char rarr boolis uppercase IsUpper char rarr boolparse binary FromBinString string rarr num optionparse decimal FromDecString string rarr num optionparse hexadecimal FromHexString string rarr num optionconvert to lowercase ToLower string rarr stringconvert to uppercase ToUpper string rarr string

The following string operations are useful for parsing

split from the left splitl (char rarr bool) times string rarr string times stringsplit from the right splitr (char rarr bool) times string rarr string times stringsplit into fields fields (char rarr bool) times string rarr string listsplit into tokens tokens (char rarr bool) times string rarr string list

These are based on the SML functions Substringsplitl Substringsplitr Stringfieldsand Stringtokens Character predicates are declared using special syntax for example theexpression

splitl space or hexdigit and not in set a f ( 12bcab)

gives the result lsquo( 12bc ab)rsquo

26

A8 Floating-pointThe L3 language does not provide specialised types for representing floating-point numbersHowever 32-bit (single precision) and 64-bit (double precision) bit-vector values can be treatedas floating-point numbers the following IEEE compliant encoding formats are assumed

31 30 23 22 0

s e m1 8 23

63 62 52 51 0

s e m1 11 52

Here lsquosrsquo is the sign bit (set to lsquo1rsquo for negative numbers) lsquoersquo is a biased exponent value and lsquomrsquo is thesignificand The following constants and operations are available (where lsquofprsquo stands for bits(32)or bits(64) depending on the name of the operation)

rounding modes roundTiesToEvenroundTowardPositiveroundTowardNegativeroundTowardZero

ieee_rounding

flags (record) DivideByZero InvalidOpOverflow PrecisionUnderflow

ieee_flagsrarrbool

comparison values FP_LT FP_EQ FP_GT FP_UN ieee_compare

convert format FP32_ToFP64 fp32rarrfp64convert format FP64_ToFP32 ieee_roundingtimes fp64rarrfp32convert format FP64_ToFP32_ ieee_roundingtimes fp64rarr

ieee_flagstimes fp32from integer FP32|64_FromInt ieee_roundingtimes intrarrfpto integer FP32|64_ToInt ieee_roundingtimes fprarrint optionfrom string FP32|64 stringrarrfp

negative zero FP32|64_NegZero fppositive zero FP32|64_PosZero fpnegative infinity FP32|64_NegInf fppositive infinity FP32|64_PosInf fpa quiet NaN FP32|64_qNan fpa signalling NaN FP32|64_sNan fp

is integral FP32|64_IsIntegral fprarrboolis finite FP32|64_IsFinite fprarrboolis NaN FP32|64_IsNan fprarrboolis signalling NaN FP32|64_IsSignallingNan fprarrboolis normal FP32|64_IsNormal fprarrboolis sub-normal FP32|64_IsSubnormal fprarrboolis zero FP32|64_IsZero fprarrbool

27

comparison FP32|64_Compare fptimes fprarrieee_compareequality FP32|64_Equal fptimes fprarrboolless than FP32|64_LessThan fptimes fprarrboolless than or equal FP32|64_LessEqual fptimes fprarrboolgreater than FP32|64_GreaterThan fptimes fprarrboolgreater than or equal FP32|64_GreaterEqual fptimes fprarrbool

absolute FP32|64_Abs fprarrfpnegation FP32|64_Neg fprarrfpsquare root FP32|64_Sqrt ieee_roundingtimes fprarrfp(with flags) FP32|64_Sqrt_ ieee_roundingtimes fprarrieee_flagstimes fpaddition FP32|64_Add ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Add_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpsubtraction FP32|64_Sub ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Sub_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpmultiplication FP32|64_Mul ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Mul_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpfused multiply-add FP32|64_MulAdd ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulAdd_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpfused multiply-sub FP32|64_MulSub ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulSub_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpdivision FP32|64_Div ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Div_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fp

The L3 interpreter supports evaluation for 32-bit and 64-bit floating-point expressions but onlywhen running on an x86 machine that supports SSE2 extensions (Pentium 4 and later) Thefused multiply-addsub operations can only be interpreted on machines supporting the FMAextension which came in with the 4th generation (Haswell) Intel processors These restrictionsalso apply to any Standard ML code that is generated by L3

The IEEE 754 standard permits a number of different ways to flag underflow L3 predomi-nantly supports the x86 interpretation which detects underflow after rounding However whenexporting to HOL4 it is possible to choose detection before rounding which for example issuited to ARM instruction set models

A9 Miscellaneous operationsThe following operations are available

pair constructor αtimes β rarr αtimes βfirst of pair Fst αtimes β rarr αsecond of pair Snd αtimes β rarr β

casting [middot] α rarr βinitialise a map InitMap α rarr (βrarrα)

28

option constructor Some αrarrα optionoption projection ValOf α option rarr αoption test IsSome α option rarr bool

set membership in αtimesα set rarr boolset non-membership notin αtimesα set rarr boolset insertion insert αtimesα set rarrα setset union Union α settimesα set rarrα setset intersection Intersect α settimesα set rarrα setset difference Difference α settimesα set rarrα setset subset test IsSubset α settimesα set rarr boolset cardinality Cardinality α setrarr natset from a list SetOfList α list rarrα set

empty list Nil α listlist constructor Cons αtimesα list rarr α listlist head Head α list rarr αlist tail Tail α list rarr α listlist length Length α list rarr natlist concatenation α listtimesα list rarr α listlist flatten Concat α list list rarr α listlist element Element nattimesα list rarr αlist prefix Take nattimesα list rarr α listlist drop prefix Drop nattimesα list rarr α listlist pad left PadLeft αtimes nattimesα list rarr α listlist pad right PadRight αtimes nattimesα list rarr α listlist update Update αtimes nattimesα list rarr α listlist difference Remove α listtimesα list rarr α listlist intersection RemoveExcept α listtimesα list rarr α listlist without duplicates RemoveDuplicates α listrarr α listlist membership IsMember αtimesα list rarr boollist member position IndexOf αtimesα list rarr nat option

Sets are only defined over equality types see Appendix A2 The casting map is defined overcast-able types (as represented by the polymorphic type variables α and β) these are the primitivetypes (with the exception of lsquounitrsquo) and user defined enumerated types Assume lsquoEnumrsquo and lsquoEnum2rsquoare declared with

construct Enum One Two Three construct Enum2 Four Five Six Seven

The cast operations are described in Tables 1 to 7

29

Table 1 Cast to lsquoboolrsquo

From Operation Examples

bool identity lsquo[true]boolrsquo = lsquotruersquostring parse bool lsquo[true]boolrsquo = lsquotruersquo

lsquo[false]boolrsquo = lsquofalsersquootherwise undefined

nat is not zero lsquo[0n3]boolrsquo = lsquotruersquolsquo[0n0]boolrsquo = lsquofalsersquo

int is not zero lsquo[-0i1]boolrsquo = lsquotruersquolsquo[0i0]boolrsquo = lsquofalsersquo

bool list is not zero lsquo[0s11]boolrsquo = lsquotruersquolsquo[0s0]boolrsquo = lsquofalsersquo

bits(middot) is not zero lsquo[3`3]boolrsquo = lsquotruersquolsquo[0`3]boolrsquo = lsquofalsersquo

Enum is not the first element lsquo[One]boolrsquo = lsquofalsersquolsquo[Two]boolrsquo = lsquotruersquo

Table 2 Cast to lsquostringrsquo

From Operation Examples

bool name lsquo[true]stringrsquo = lsquotruersquostring identity lsquo[hello]stringrsquo = lsquohellorsquonat decimal lsquo[0n3]stringrsquo = lsquo3rsquoint signed decimal lsquo[-0i1]stringrsquo = lsquo~1rsquobool list binary lsquo[0s11]stringrsquo = lsquo11rsquobits(middot) unsigned hexadecimal lsquo[139`8]stringrsquo = lsquo8BrsquoEnum name lsquo[One]stringrsquo = lsquoOnersquo

30

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

left-shift ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (u) gtgt+ bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

right-shift (s) gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate left ltlt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

rotate right gtgt bits(n)times nat rarr bits(n)bits(n)times bits(n) rarr bits(n)

A number of operations are undefined depending on the types of their domain and rangeThis is detailed in the following table

Operation Undefined when

ZeroExtend(x`n)`m m lt nSignExtend(x`n)`m m lt n(x`m)ltpgt m le p(x`m)lthlgt`n n = h+ 1minus l or h lt l orm le h((xm) (yn))`p p = m+ n((x`m) ^ n)`p p = m middot n (which covers n = 0)

The type checker will fail when these conditions are obviously violated Alternatively the inter-preter may raise a runtime error when these conditions are not met

As before the expressions lsquoLog2(0)rsquo lsquox quot 0rsquo lsquox rem 0rsquo lsquox div 0rsquo and lsquox mod 0rsquo are allundefined

A6 Bit-stringsVarious bit-string operation are defined over the type lsquobool listrsquo These are listed below

bit value middot ltmiddotgt bool listtimes nat rarr boolbit field middot ltmiddotmiddotgt bool listtimes nattimes nat rarr bool listconcatenation bool listtimes bool list rarr bool listduplication ^ bool listtimes nat rarr bool listaddition + bool listtimes bool list rarr bool listbitwise conjunction ampamp bool listtimes bool list rarr bool listbitwise disjunction || bool listtimes bool list rarr bool listbitwise exclusive-or bool listtimes bool list rarr bool listleft-shift ltlt bool listtimes nat rarr bool listright-shift gtgt+ bool listtimes nat rarr bool listrotate-right gtgt bool listtimes nat rarr bool list

The bit value operation gives the truth value of a bit-string at a given bit position for example

lsquo0s1101lt0gtrsquo = lsquotruersquo lsquo0s1101lt1gtrsquo = lsquofalsersquo lsquo0s1101lt2gtrsquo = lsquotruersquolsquo0s1101lt3gtrsquo = lsquotruersquo lsquo0s1101lt4gtrsquo = lsquofalsersquo lsquo0s1101lt5gtrsquo = lsquofalsersquo

25

The least-significant bit (position zero) occurs to the right of the bit-string The bit value oper-ation gives lsquofalsersquo when the bit position is greater than the size of the bit-string

The bit field operation extracts a range of bits from a bit-string For example

lsquo0s1101lt31gtrsquo = lsquo0s110rsquo and lsquo0s1101lt52gtrsquo = lsquo0s0011rsquo

In the bit-string expression xlthlgt the size of the result is always h + 1 minus l and the result isundefined when h lt l

Bit-string addition does not require the arguments to be of the same size and it gives anon-truncated result For example

lsquo0s101 + 0s1rsquo = lsquo0s110rsquo and lsquo0s101 + 0s11rsquo = lsquo0s1000rsquo

The operation ltlt performs a left-shift for example lsquo0s1101 ltlt 2rsquo = lsquo0s110100rsquo The oper-ation lsquorsquo is bit-string concatenation and lsquo^rsquo is duplication for example

lsquo0s101 0s11rsquo = lsquo0s10111rsquo and lsquo0s101 ^ 3rsquo = lsquo0s101101101rsquo

Regular list operations work as one would expect over bit-strings for example lsquoHead (0s101)rsquois a valid expression with value lsquotruersquo

A7 Characters and StringsThe following built-in functions are available for characters and strings

is alphabetic IsAlpha char rarr boolis alpha-numeric IsAlphaNum char rarr boolis decimal digit IsDigit char rarr boolis hexadecimal digit IsHexDigit char rarr boolis lowercase IsLower char rarr boolis uppercase IsUpper char rarr boolparse binary FromBinString string rarr num optionparse decimal FromDecString string rarr num optionparse hexadecimal FromHexString string rarr num optionconvert to lowercase ToLower string rarr stringconvert to uppercase ToUpper string rarr string

The following string operations are useful for parsing

split from the left splitl (char rarr bool) times string rarr string times stringsplit from the right splitr (char rarr bool) times string rarr string times stringsplit into fields fields (char rarr bool) times string rarr string listsplit into tokens tokens (char rarr bool) times string rarr string list

These are based on the SML functions Substringsplitl Substringsplitr Stringfieldsand Stringtokens Character predicates are declared using special syntax for example theexpression

splitl space or hexdigit and not in set a f ( 12bcab)

gives the result lsquo( 12bc ab)rsquo

26

A8 Floating-pointThe L3 language does not provide specialised types for representing floating-point numbersHowever 32-bit (single precision) and 64-bit (double precision) bit-vector values can be treatedas floating-point numbers the following IEEE compliant encoding formats are assumed

31 30 23 22 0

s e m1 8 23

63 62 52 51 0

s e m1 11 52

Here lsquosrsquo is the sign bit (set to lsquo1rsquo for negative numbers) lsquoersquo is a biased exponent value and lsquomrsquo is thesignificand The following constants and operations are available (where lsquofprsquo stands for bits(32)or bits(64) depending on the name of the operation)

rounding modes roundTiesToEvenroundTowardPositiveroundTowardNegativeroundTowardZero

ieee_rounding

flags (record) DivideByZero InvalidOpOverflow PrecisionUnderflow

ieee_flagsrarrbool

comparison values FP_LT FP_EQ FP_GT FP_UN ieee_compare

convert format FP32_ToFP64 fp32rarrfp64convert format FP64_ToFP32 ieee_roundingtimes fp64rarrfp32convert format FP64_ToFP32_ ieee_roundingtimes fp64rarr

ieee_flagstimes fp32from integer FP32|64_FromInt ieee_roundingtimes intrarrfpto integer FP32|64_ToInt ieee_roundingtimes fprarrint optionfrom string FP32|64 stringrarrfp

negative zero FP32|64_NegZero fppositive zero FP32|64_PosZero fpnegative infinity FP32|64_NegInf fppositive infinity FP32|64_PosInf fpa quiet NaN FP32|64_qNan fpa signalling NaN FP32|64_sNan fp

is integral FP32|64_IsIntegral fprarrboolis finite FP32|64_IsFinite fprarrboolis NaN FP32|64_IsNan fprarrboolis signalling NaN FP32|64_IsSignallingNan fprarrboolis normal FP32|64_IsNormal fprarrboolis sub-normal FP32|64_IsSubnormal fprarrboolis zero FP32|64_IsZero fprarrbool

27

comparison FP32|64_Compare fptimes fprarrieee_compareequality FP32|64_Equal fptimes fprarrboolless than FP32|64_LessThan fptimes fprarrboolless than or equal FP32|64_LessEqual fptimes fprarrboolgreater than FP32|64_GreaterThan fptimes fprarrboolgreater than or equal FP32|64_GreaterEqual fptimes fprarrbool

absolute FP32|64_Abs fprarrfpnegation FP32|64_Neg fprarrfpsquare root FP32|64_Sqrt ieee_roundingtimes fprarrfp(with flags) FP32|64_Sqrt_ ieee_roundingtimes fprarrieee_flagstimes fpaddition FP32|64_Add ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Add_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpsubtraction FP32|64_Sub ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Sub_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpmultiplication FP32|64_Mul ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Mul_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpfused multiply-add FP32|64_MulAdd ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulAdd_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpfused multiply-sub FP32|64_MulSub ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulSub_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpdivision FP32|64_Div ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Div_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fp

The L3 interpreter supports evaluation for 32-bit and 64-bit floating-point expressions but onlywhen running on an x86 machine that supports SSE2 extensions (Pentium 4 and later) Thefused multiply-addsub operations can only be interpreted on machines supporting the FMAextension which came in with the 4th generation (Haswell) Intel processors These restrictionsalso apply to any Standard ML code that is generated by L3

The IEEE 754 standard permits a number of different ways to flag underflow L3 predomi-nantly supports the x86 interpretation which detects underflow after rounding However whenexporting to HOL4 it is possible to choose detection before rounding which for example issuited to ARM instruction set models

A9 Miscellaneous operationsThe following operations are available

pair constructor αtimes β rarr αtimes βfirst of pair Fst αtimes β rarr αsecond of pair Snd αtimes β rarr β

casting [middot] α rarr βinitialise a map InitMap α rarr (βrarrα)

28

option constructor Some αrarrα optionoption projection ValOf α option rarr αoption test IsSome α option rarr bool

set membership in αtimesα set rarr boolset non-membership notin αtimesα set rarr boolset insertion insert αtimesα set rarrα setset union Union α settimesα set rarrα setset intersection Intersect α settimesα set rarrα setset difference Difference α settimesα set rarrα setset subset test IsSubset α settimesα set rarr boolset cardinality Cardinality α setrarr natset from a list SetOfList α list rarrα set

empty list Nil α listlist constructor Cons αtimesα list rarr α listlist head Head α list rarr αlist tail Tail α list rarr α listlist length Length α list rarr natlist concatenation α listtimesα list rarr α listlist flatten Concat α list list rarr α listlist element Element nattimesα list rarr αlist prefix Take nattimesα list rarr α listlist drop prefix Drop nattimesα list rarr α listlist pad left PadLeft αtimes nattimesα list rarr α listlist pad right PadRight αtimes nattimesα list rarr α listlist update Update αtimes nattimesα list rarr α listlist difference Remove α listtimesα list rarr α listlist intersection RemoveExcept α listtimesα list rarr α listlist without duplicates RemoveDuplicates α listrarr α listlist membership IsMember αtimesα list rarr boollist member position IndexOf αtimesα list rarr nat option

Sets are only defined over equality types see Appendix A2 The casting map is defined overcast-able types (as represented by the polymorphic type variables α and β) these are the primitivetypes (with the exception of lsquounitrsquo) and user defined enumerated types Assume lsquoEnumrsquo and lsquoEnum2rsquoare declared with

construct Enum One Two Three construct Enum2 Four Five Six Seven

The cast operations are described in Tables 1 to 7

29

Table 1 Cast to lsquoboolrsquo

From Operation Examples

bool identity lsquo[true]boolrsquo = lsquotruersquostring parse bool lsquo[true]boolrsquo = lsquotruersquo

lsquo[false]boolrsquo = lsquofalsersquootherwise undefined

nat is not zero lsquo[0n3]boolrsquo = lsquotruersquolsquo[0n0]boolrsquo = lsquofalsersquo

int is not zero lsquo[-0i1]boolrsquo = lsquotruersquolsquo[0i0]boolrsquo = lsquofalsersquo

bool list is not zero lsquo[0s11]boolrsquo = lsquotruersquolsquo[0s0]boolrsquo = lsquofalsersquo

bits(middot) is not zero lsquo[3`3]boolrsquo = lsquotruersquolsquo[0`3]boolrsquo = lsquofalsersquo

Enum is not the first element lsquo[One]boolrsquo = lsquofalsersquolsquo[Two]boolrsquo = lsquotruersquo

Table 2 Cast to lsquostringrsquo

From Operation Examples

bool name lsquo[true]stringrsquo = lsquotruersquostring identity lsquo[hello]stringrsquo = lsquohellorsquonat decimal lsquo[0n3]stringrsquo = lsquo3rsquoint signed decimal lsquo[-0i1]stringrsquo = lsquo~1rsquobool list binary lsquo[0s11]stringrsquo = lsquo11rsquobits(middot) unsigned hexadecimal lsquo[139`8]stringrsquo = lsquo8BrsquoEnum name lsquo[One]stringrsquo = lsquoOnersquo

30

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

The least-significant bit (position zero) occurs to the right of the bit-string The bit value oper-ation gives lsquofalsersquo when the bit position is greater than the size of the bit-string

The bit field operation extracts a range of bits from a bit-string For example

lsquo0s1101lt31gtrsquo = lsquo0s110rsquo and lsquo0s1101lt52gtrsquo = lsquo0s0011rsquo

In the bit-string expression xlthlgt the size of the result is always h + 1 minus l and the result isundefined when h lt l

Bit-string addition does not require the arguments to be of the same size and it gives anon-truncated result For example

lsquo0s101 + 0s1rsquo = lsquo0s110rsquo and lsquo0s101 + 0s11rsquo = lsquo0s1000rsquo

The operation ltlt performs a left-shift for example lsquo0s1101 ltlt 2rsquo = lsquo0s110100rsquo The oper-ation lsquorsquo is bit-string concatenation and lsquo^rsquo is duplication for example

lsquo0s101 0s11rsquo = lsquo0s10111rsquo and lsquo0s101 ^ 3rsquo = lsquo0s101101101rsquo

Regular list operations work as one would expect over bit-strings for example lsquoHead (0s101)rsquois a valid expression with value lsquotruersquo

A7 Characters and StringsThe following built-in functions are available for characters and strings

is alphabetic IsAlpha char rarr boolis alpha-numeric IsAlphaNum char rarr boolis decimal digit IsDigit char rarr boolis hexadecimal digit IsHexDigit char rarr boolis lowercase IsLower char rarr boolis uppercase IsUpper char rarr boolparse binary FromBinString string rarr num optionparse decimal FromDecString string rarr num optionparse hexadecimal FromHexString string rarr num optionconvert to lowercase ToLower string rarr stringconvert to uppercase ToUpper string rarr string

The following string operations are useful for parsing

split from the left splitl (char rarr bool) times string rarr string times stringsplit from the right splitr (char rarr bool) times string rarr string times stringsplit into fields fields (char rarr bool) times string rarr string listsplit into tokens tokens (char rarr bool) times string rarr string list

These are based on the SML functions Substringsplitl Substringsplitr Stringfieldsand Stringtokens Character predicates are declared using special syntax for example theexpression

splitl space or hexdigit and not in set a f ( 12bcab)

gives the result lsquo( 12bc ab)rsquo

26

A8 Floating-pointThe L3 language does not provide specialised types for representing floating-point numbersHowever 32-bit (single precision) and 64-bit (double precision) bit-vector values can be treatedas floating-point numbers the following IEEE compliant encoding formats are assumed

31 30 23 22 0

s e m1 8 23

63 62 52 51 0

s e m1 11 52

Here lsquosrsquo is the sign bit (set to lsquo1rsquo for negative numbers) lsquoersquo is a biased exponent value and lsquomrsquo is thesignificand The following constants and operations are available (where lsquofprsquo stands for bits(32)or bits(64) depending on the name of the operation)

rounding modes roundTiesToEvenroundTowardPositiveroundTowardNegativeroundTowardZero

ieee_rounding

flags (record) DivideByZero InvalidOpOverflow PrecisionUnderflow

ieee_flagsrarrbool

comparison values FP_LT FP_EQ FP_GT FP_UN ieee_compare

convert format FP32_ToFP64 fp32rarrfp64convert format FP64_ToFP32 ieee_roundingtimes fp64rarrfp32convert format FP64_ToFP32_ ieee_roundingtimes fp64rarr

ieee_flagstimes fp32from integer FP32|64_FromInt ieee_roundingtimes intrarrfpto integer FP32|64_ToInt ieee_roundingtimes fprarrint optionfrom string FP32|64 stringrarrfp

negative zero FP32|64_NegZero fppositive zero FP32|64_PosZero fpnegative infinity FP32|64_NegInf fppositive infinity FP32|64_PosInf fpa quiet NaN FP32|64_qNan fpa signalling NaN FP32|64_sNan fp

is integral FP32|64_IsIntegral fprarrboolis finite FP32|64_IsFinite fprarrboolis NaN FP32|64_IsNan fprarrboolis signalling NaN FP32|64_IsSignallingNan fprarrboolis normal FP32|64_IsNormal fprarrboolis sub-normal FP32|64_IsSubnormal fprarrboolis zero FP32|64_IsZero fprarrbool

27

comparison FP32|64_Compare fptimes fprarrieee_compareequality FP32|64_Equal fptimes fprarrboolless than FP32|64_LessThan fptimes fprarrboolless than or equal FP32|64_LessEqual fptimes fprarrboolgreater than FP32|64_GreaterThan fptimes fprarrboolgreater than or equal FP32|64_GreaterEqual fptimes fprarrbool

absolute FP32|64_Abs fprarrfpnegation FP32|64_Neg fprarrfpsquare root FP32|64_Sqrt ieee_roundingtimes fprarrfp(with flags) FP32|64_Sqrt_ ieee_roundingtimes fprarrieee_flagstimes fpaddition FP32|64_Add ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Add_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpsubtraction FP32|64_Sub ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Sub_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpmultiplication FP32|64_Mul ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Mul_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpfused multiply-add FP32|64_MulAdd ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulAdd_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpfused multiply-sub FP32|64_MulSub ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulSub_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpdivision FP32|64_Div ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Div_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fp

The L3 interpreter supports evaluation for 32-bit and 64-bit floating-point expressions but onlywhen running on an x86 machine that supports SSE2 extensions (Pentium 4 and later) Thefused multiply-addsub operations can only be interpreted on machines supporting the FMAextension which came in with the 4th generation (Haswell) Intel processors These restrictionsalso apply to any Standard ML code that is generated by L3

The IEEE 754 standard permits a number of different ways to flag underflow L3 predomi-nantly supports the x86 interpretation which detects underflow after rounding However whenexporting to HOL4 it is possible to choose detection before rounding which for example issuited to ARM instruction set models

A9 Miscellaneous operationsThe following operations are available

pair constructor αtimes β rarr αtimes βfirst of pair Fst αtimes β rarr αsecond of pair Snd αtimes β rarr β

casting [middot] α rarr βinitialise a map InitMap α rarr (βrarrα)

28

option constructor Some αrarrα optionoption projection ValOf α option rarr αoption test IsSome α option rarr bool

set membership in αtimesα set rarr boolset non-membership notin αtimesα set rarr boolset insertion insert αtimesα set rarrα setset union Union α settimesα set rarrα setset intersection Intersect α settimesα set rarrα setset difference Difference α settimesα set rarrα setset subset test IsSubset α settimesα set rarr boolset cardinality Cardinality α setrarr natset from a list SetOfList α list rarrα set

empty list Nil α listlist constructor Cons αtimesα list rarr α listlist head Head α list rarr αlist tail Tail α list rarr α listlist length Length α list rarr natlist concatenation α listtimesα list rarr α listlist flatten Concat α list list rarr α listlist element Element nattimesα list rarr αlist prefix Take nattimesα list rarr α listlist drop prefix Drop nattimesα list rarr α listlist pad left PadLeft αtimes nattimesα list rarr α listlist pad right PadRight αtimes nattimesα list rarr α listlist update Update αtimes nattimesα list rarr α listlist difference Remove α listtimesα list rarr α listlist intersection RemoveExcept α listtimesα list rarr α listlist without duplicates RemoveDuplicates α listrarr α listlist membership IsMember αtimesα list rarr boollist member position IndexOf αtimesα list rarr nat option

Sets are only defined over equality types see Appendix A2 The casting map is defined overcast-able types (as represented by the polymorphic type variables α and β) these are the primitivetypes (with the exception of lsquounitrsquo) and user defined enumerated types Assume lsquoEnumrsquo and lsquoEnum2rsquoare declared with

construct Enum One Two Three construct Enum2 Four Five Six Seven

The cast operations are described in Tables 1 to 7

29

Table 1 Cast to lsquoboolrsquo

From Operation Examples

bool identity lsquo[true]boolrsquo = lsquotruersquostring parse bool lsquo[true]boolrsquo = lsquotruersquo

lsquo[false]boolrsquo = lsquofalsersquootherwise undefined

nat is not zero lsquo[0n3]boolrsquo = lsquotruersquolsquo[0n0]boolrsquo = lsquofalsersquo

int is not zero lsquo[-0i1]boolrsquo = lsquotruersquolsquo[0i0]boolrsquo = lsquofalsersquo

bool list is not zero lsquo[0s11]boolrsquo = lsquotruersquolsquo[0s0]boolrsquo = lsquofalsersquo

bits(middot) is not zero lsquo[3`3]boolrsquo = lsquotruersquolsquo[0`3]boolrsquo = lsquofalsersquo

Enum is not the first element lsquo[One]boolrsquo = lsquofalsersquolsquo[Two]boolrsquo = lsquotruersquo

Table 2 Cast to lsquostringrsquo

From Operation Examples

bool name lsquo[true]stringrsquo = lsquotruersquostring identity lsquo[hello]stringrsquo = lsquohellorsquonat decimal lsquo[0n3]stringrsquo = lsquo3rsquoint signed decimal lsquo[-0i1]stringrsquo = lsquo~1rsquobool list binary lsquo[0s11]stringrsquo = lsquo11rsquobits(middot) unsigned hexadecimal lsquo[139`8]stringrsquo = lsquo8BrsquoEnum name lsquo[One]stringrsquo = lsquoOnersquo

30

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

A8 Floating-pointThe L3 language does not provide specialised types for representing floating-point numbersHowever 32-bit (single precision) and 64-bit (double precision) bit-vector values can be treatedas floating-point numbers the following IEEE compliant encoding formats are assumed

31 30 23 22 0

s e m1 8 23

63 62 52 51 0

s e m1 11 52

Here lsquosrsquo is the sign bit (set to lsquo1rsquo for negative numbers) lsquoersquo is a biased exponent value and lsquomrsquo is thesignificand The following constants and operations are available (where lsquofprsquo stands for bits(32)or bits(64) depending on the name of the operation)

rounding modes roundTiesToEvenroundTowardPositiveroundTowardNegativeroundTowardZero

ieee_rounding

flags (record) DivideByZero InvalidOpOverflow PrecisionUnderflow

ieee_flagsrarrbool

comparison values FP_LT FP_EQ FP_GT FP_UN ieee_compare

convert format FP32_ToFP64 fp32rarrfp64convert format FP64_ToFP32 ieee_roundingtimes fp64rarrfp32convert format FP64_ToFP32_ ieee_roundingtimes fp64rarr

ieee_flagstimes fp32from integer FP32|64_FromInt ieee_roundingtimes intrarrfpto integer FP32|64_ToInt ieee_roundingtimes fprarrint optionfrom string FP32|64 stringrarrfp

negative zero FP32|64_NegZero fppositive zero FP32|64_PosZero fpnegative infinity FP32|64_NegInf fppositive infinity FP32|64_PosInf fpa quiet NaN FP32|64_qNan fpa signalling NaN FP32|64_sNan fp

is integral FP32|64_IsIntegral fprarrboolis finite FP32|64_IsFinite fprarrboolis NaN FP32|64_IsNan fprarrboolis signalling NaN FP32|64_IsSignallingNan fprarrboolis normal FP32|64_IsNormal fprarrboolis sub-normal FP32|64_IsSubnormal fprarrboolis zero FP32|64_IsZero fprarrbool

27

comparison FP32|64_Compare fptimes fprarrieee_compareequality FP32|64_Equal fptimes fprarrboolless than FP32|64_LessThan fptimes fprarrboolless than or equal FP32|64_LessEqual fptimes fprarrboolgreater than FP32|64_GreaterThan fptimes fprarrboolgreater than or equal FP32|64_GreaterEqual fptimes fprarrbool

absolute FP32|64_Abs fprarrfpnegation FP32|64_Neg fprarrfpsquare root FP32|64_Sqrt ieee_roundingtimes fprarrfp(with flags) FP32|64_Sqrt_ ieee_roundingtimes fprarrieee_flagstimes fpaddition FP32|64_Add ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Add_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpsubtraction FP32|64_Sub ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Sub_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpmultiplication FP32|64_Mul ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Mul_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpfused multiply-add FP32|64_MulAdd ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulAdd_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpfused multiply-sub FP32|64_MulSub ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulSub_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpdivision FP32|64_Div ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Div_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fp

The L3 interpreter supports evaluation for 32-bit and 64-bit floating-point expressions but onlywhen running on an x86 machine that supports SSE2 extensions (Pentium 4 and later) Thefused multiply-addsub operations can only be interpreted on machines supporting the FMAextension which came in with the 4th generation (Haswell) Intel processors These restrictionsalso apply to any Standard ML code that is generated by L3

The IEEE 754 standard permits a number of different ways to flag underflow L3 predomi-nantly supports the x86 interpretation which detects underflow after rounding However whenexporting to HOL4 it is possible to choose detection before rounding which for example issuited to ARM instruction set models

A9 Miscellaneous operationsThe following operations are available

pair constructor αtimes β rarr αtimes βfirst of pair Fst αtimes β rarr αsecond of pair Snd αtimes β rarr β

casting [middot] α rarr βinitialise a map InitMap α rarr (βrarrα)

28

option constructor Some αrarrα optionoption projection ValOf α option rarr αoption test IsSome α option rarr bool

set membership in αtimesα set rarr boolset non-membership notin αtimesα set rarr boolset insertion insert αtimesα set rarrα setset union Union α settimesα set rarrα setset intersection Intersect α settimesα set rarrα setset difference Difference α settimesα set rarrα setset subset test IsSubset α settimesα set rarr boolset cardinality Cardinality α setrarr natset from a list SetOfList α list rarrα set

empty list Nil α listlist constructor Cons αtimesα list rarr α listlist head Head α list rarr αlist tail Tail α list rarr α listlist length Length α list rarr natlist concatenation α listtimesα list rarr α listlist flatten Concat α list list rarr α listlist element Element nattimesα list rarr αlist prefix Take nattimesα list rarr α listlist drop prefix Drop nattimesα list rarr α listlist pad left PadLeft αtimes nattimesα list rarr α listlist pad right PadRight αtimes nattimesα list rarr α listlist update Update αtimes nattimesα list rarr α listlist difference Remove α listtimesα list rarr α listlist intersection RemoveExcept α listtimesα list rarr α listlist without duplicates RemoveDuplicates α listrarr α listlist membership IsMember αtimesα list rarr boollist member position IndexOf αtimesα list rarr nat option

Sets are only defined over equality types see Appendix A2 The casting map is defined overcast-able types (as represented by the polymorphic type variables α and β) these are the primitivetypes (with the exception of lsquounitrsquo) and user defined enumerated types Assume lsquoEnumrsquo and lsquoEnum2rsquoare declared with

construct Enum One Two Three construct Enum2 Four Five Six Seven

The cast operations are described in Tables 1 to 7

29

Table 1 Cast to lsquoboolrsquo

From Operation Examples

bool identity lsquo[true]boolrsquo = lsquotruersquostring parse bool lsquo[true]boolrsquo = lsquotruersquo

lsquo[false]boolrsquo = lsquofalsersquootherwise undefined

nat is not zero lsquo[0n3]boolrsquo = lsquotruersquolsquo[0n0]boolrsquo = lsquofalsersquo

int is not zero lsquo[-0i1]boolrsquo = lsquotruersquolsquo[0i0]boolrsquo = lsquofalsersquo

bool list is not zero lsquo[0s11]boolrsquo = lsquotruersquolsquo[0s0]boolrsquo = lsquofalsersquo

bits(middot) is not zero lsquo[3`3]boolrsquo = lsquotruersquolsquo[0`3]boolrsquo = lsquofalsersquo

Enum is not the first element lsquo[One]boolrsquo = lsquofalsersquolsquo[Two]boolrsquo = lsquotruersquo

Table 2 Cast to lsquostringrsquo

From Operation Examples

bool name lsquo[true]stringrsquo = lsquotruersquostring identity lsquo[hello]stringrsquo = lsquohellorsquonat decimal lsquo[0n3]stringrsquo = lsquo3rsquoint signed decimal lsquo[-0i1]stringrsquo = lsquo~1rsquobool list binary lsquo[0s11]stringrsquo = lsquo11rsquobits(middot) unsigned hexadecimal lsquo[139`8]stringrsquo = lsquo8BrsquoEnum name lsquo[One]stringrsquo = lsquoOnersquo

30

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

comparison FP32|64_Compare fptimes fprarrieee_compareequality FP32|64_Equal fptimes fprarrboolless than FP32|64_LessThan fptimes fprarrboolless than or equal FP32|64_LessEqual fptimes fprarrboolgreater than FP32|64_GreaterThan fptimes fprarrboolgreater than or equal FP32|64_GreaterEqual fptimes fprarrbool

absolute FP32|64_Abs fprarrfpnegation FP32|64_Neg fprarrfpsquare root FP32|64_Sqrt ieee_roundingtimes fprarrfp(with flags) FP32|64_Sqrt_ ieee_roundingtimes fprarrieee_flagstimes fpaddition FP32|64_Add ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Add_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpsubtraction FP32|64_Sub ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Sub_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpmultiplication FP32|64_Mul ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Mul_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fpfused multiply-add FP32|64_MulAdd ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulAdd_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpfused multiply-sub FP32|64_MulSub ieee_roundingtimes fptimes fptimes fprarrfp(with flags) FP32|64_MulSub_ ieee_roundingtimes fptimes fptimes fprarr

ieee_flagstimes fpdivision FP32|64_Div ieee_roundingtimes fptimes fprarrfp(with flags) FP32|64_Div_ ieee_roundingtimes fptimes fprarr

ieee_flagstimes fp

The L3 interpreter supports evaluation for 32-bit and 64-bit floating-point expressions but onlywhen running on an x86 machine that supports SSE2 extensions (Pentium 4 and later) Thefused multiply-addsub operations can only be interpreted on machines supporting the FMAextension which came in with the 4th generation (Haswell) Intel processors These restrictionsalso apply to any Standard ML code that is generated by L3

The IEEE 754 standard permits a number of different ways to flag underflow L3 predomi-nantly supports the x86 interpretation which detects underflow after rounding However whenexporting to HOL4 it is possible to choose detection before rounding which for example issuited to ARM instruction set models

A9 Miscellaneous operationsThe following operations are available

pair constructor αtimes β rarr αtimes βfirst of pair Fst αtimes β rarr αsecond of pair Snd αtimes β rarr β

casting [middot] α rarr βinitialise a map InitMap α rarr (βrarrα)

28

option constructor Some αrarrα optionoption projection ValOf α option rarr αoption test IsSome α option rarr bool

set membership in αtimesα set rarr boolset non-membership notin αtimesα set rarr boolset insertion insert αtimesα set rarrα setset union Union α settimesα set rarrα setset intersection Intersect α settimesα set rarrα setset difference Difference α settimesα set rarrα setset subset test IsSubset α settimesα set rarr boolset cardinality Cardinality α setrarr natset from a list SetOfList α list rarrα set

empty list Nil α listlist constructor Cons αtimesα list rarr α listlist head Head α list rarr αlist tail Tail α list rarr α listlist length Length α list rarr natlist concatenation α listtimesα list rarr α listlist flatten Concat α list list rarr α listlist element Element nattimesα list rarr αlist prefix Take nattimesα list rarr α listlist drop prefix Drop nattimesα list rarr α listlist pad left PadLeft αtimes nattimesα list rarr α listlist pad right PadRight αtimes nattimesα list rarr α listlist update Update αtimes nattimesα list rarr α listlist difference Remove α listtimesα list rarr α listlist intersection RemoveExcept α listtimesα list rarr α listlist without duplicates RemoveDuplicates α listrarr α listlist membership IsMember αtimesα list rarr boollist member position IndexOf αtimesα list rarr nat option

Sets are only defined over equality types see Appendix A2 The casting map is defined overcast-able types (as represented by the polymorphic type variables α and β) these are the primitivetypes (with the exception of lsquounitrsquo) and user defined enumerated types Assume lsquoEnumrsquo and lsquoEnum2rsquoare declared with

construct Enum One Two Three construct Enum2 Four Five Six Seven

The cast operations are described in Tables 1 to 7

29

Table 1 Cast to lsquoboolrsquo

From Operation Examples

bool identity lsquo[true]boolrsquo = lsquotruersquostring parse bool lsquo[true]boolrsquo = lsquotruersquo

lsquo[false]boolrsquo = lsquofalsersquootherwise undefined

nat is not zero lsquo[0n3]boolrsquo = lsquotruersquolsquo[0n0]boolrsquo = lsquofalsersquo

int is not zero lsquo[-0i1]boolrsquo = lsquotruersquolsquo[0i0]boolrsquo = lsquofalsersquo

bool list is not zero lsquo[0s11]boolrsquo = lsquotruersquolsquo[0s0]boolrsquo = lsquofalsersquo

bits(middot) is not zero lsquo[3`3]boolrsquo = lsquotruersquolsquo[0`3]boolrsquo = lsquofalsersquo

Enum is not the first element lsquo[One]boolrsquo = lsquofalsersquolsquo[Two]boolrsquo = lsquotruersquo

Table 2 Cast to lsquostringrsquo

From Operation Examples

bool name lsquo[true]stringrsquo = lsquotruersquostring identity lsquo[hello]stringrsquo = lsquohellorsquonat decimal lsquo[0n3]stringrsquo = lsquo3rsquoint signed decimal lsquo[-0i1]stringrsquo = lsquo~1rsquobool list binary lsquo[0s11]stringrsquo = lsquo11rsquobits(middot) unsigned hexadecimal lsquo[139`8]stringrsquo = lsquo8BrsquoEnum name lsquo[One]stringrsquo = lsquoOnersquo

30

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

option constructor Some αrarrα optionoption projection ValOf α option rarr αoption test IsSome α option rarr bool

set membership in αtimesα set rarr boolset non-membership notin αtimesα set rarr boolset insertion insert αtimesα set rarrα setset union Union α settimesα set rarrα setset intersection Intersect α settimesα set rarrα setset difference Difference α settimesα set rarrα setset subset test IsSubset α settimesα set rarr boolset cardinality Cardinality α setrarr natset from a list SetOfList α list rarrα set

empty list Nil α listlist constructor Cons αtimesα list rarr α listlist head Head α list rarr αlist tail Tail α list rarr α listlist length Length α list rarr natlist concatenation α listtimesα list rarr α listlist flatten Concat α list list rarr α listlist element Element nattimesα list rarr αlist prefix Take nattimesα list rarr α listlist drop prefix Drop nattimesα list rarr α listlist pad left PadLeft αtimes nattimesα list rarr α listlist pad right PadRight αtimes nattimesα list rarr α listlist update Update αtimes nattimesα list rarr α listlist difference Remove α listtimesα list rarr α listlist intersection RemoveExcept α listtimesα list rarr α listlist without duplicates RemoveDuplicates α listrarr α listlist membership IsMember αtimesα list rarr boollist member position IndexOf αtimesα list rarr nat option

Sets are only defined over equality types see Appendix A2 The casting map is defined overcast-able types (as represented by the polymorphic type variables α and β) these are the primitivetypes (with the exception of lsquounitrsquo) and user defined enumerated types Assume lsquoEnumrsquo and lsquoEnum2rsquoare declared with

construct Enum One Two Three construct Enum2 Four Five Six Seven

The cast operations are described in Tables 1 to 7

29

Table 1 Cast to lsquoboolrsquo

From Operation Examples

bool identity lsquo[true]boolrsquo = lsquotruersquostring parse bool lsquo[true]boolrsquo = lsquotruersquo

lsquo[false]boolrsquo = lsquofalsersquootherwise undefined

nat is not zero lsquo[0n3]boolrsquo = lsquotruersquolsquo[0n0]boolrsquo = lsquofalsersquo

int is not zero lsquo[-0i1]boolrsquo = lsquotruersquolsquo[0i0]boolrsquo = lsquofalsersquo

bool list is not zero lsquo[0s11]boolrsquo = lsquotruersquolsquo[0s0]boolrsquo = lsquofalsersquo

bits(middot) is not zero lsquo[3`3]boolrsquo = lsquotruersquolsquo[0`3]boolrsquo = lsquofalsersquo

Enum is not the first element lsquo[One]boolrsquo = lsquofalsersquolsquo[Two]boolrsquo = lsquotruersquo

Table 2 Cast to lsquostringrsquo

From Operation Examples

bool name lsquo[true]stringrsquo = lsquotruersquostring identity lsquo[hello]stringrsquo = lsquohellorsquonat decimal lsquo[0n3]stringrsquo = lsquo3rsquoint signed decimal lsquo[-0i1]stringrsquo = lsquo~1rsquobool list binary lsquo[0s11]stringrsquo = lsquo11rsquobits(middot) unsigned hexadecimal lsquo[139`8]stringrsquo = lsquo8BrsquoEnum name lsquo[One]stringrsquo = lsquoOnersquo

30

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

Table 1 Cast to lsquoboolrsquo

From Operation Examples

bool identity lsquo[true]boolrsquo = lsquotruersquostring parse bool lsquo[true]boolrsquo = lsquotruersquo

lsquo[false]boolrsquo = lsquofalsersquootherwise undefined

nat is not zero lsquo[0n3]boolrsquo = lsquotruersquolsquo[0n0]boolrsquo = lsquofalsersquo

int is not zero lsquo[-0i1]boolrsquo = lsquotruersquolsquo[0i0]boolrsquo = lsquofalsersquo

bool list is not zero lsquo[0s11]boolrsquo = lsquotruersquolsquo[0s0]boolrsquo = lsquofalsersquo

bits(middot) is not zero lsquo[3`3]boolrsquo = lsquotruersquolsquo[0`3]boolrsquo = lsquofalsersquo

Enum is not the first element lsquo[One]boolrsquo = lsquofalsersquolsquo[Two]boolrsquo = lsquotruersquo

Table 2 Cast to lsquostringrsquo

From Operation Examples

bool name lsquo[true]stringrsquo = lsquotruersquostring identity lsquo[hello]stringrsquo = lsquohellorsquonat decimal lsquo[0n3]stringrsquo = lsquo3rsquoint signed decimal lsquo[-0i1]stringrsquo = lsquo~1rsquobool list binary lsquo[0s11]stringrsquo = lsquo11rsquobits(middot) unsigned hexadecimal lsquo[139`8]stringrsquo = lsquo8BrsquoEnum name lsquo[One]stringrsquo = lsquoOnersquo

30

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

Table 3 Cast to lsquonatrsquo

From Operation Examples

bool bit value lsquo[false]natrsquo = lsquo0n0rsquolsquo[true]natrsquo = lsquo0n1rsquo

string parse decimal lsquo[123]natrsquo = lsquo0n123rsquolsquo[]natrsquo is undefinedlsquo[-1]natrsquo is undefinedlsquo[hello]natrsquo is undefined

nat identity lsquo[0n123]natrsquo = lsquo0n123rsquoint value lsquo[0i123]natrsquo = lsquo0n123rsquo

lsquo[-0i1]natrsquo is undefinedbool list value lsquo[0s11]natrsquo = lsquo0n3rsquobits(middot) unsigned value lsquo[139`8]natrsquo = lsquo0n139rsquoEnum enumerate (count from zero) lsquo[One]natrsquo = lsquo0n0rsquo

lsquo[Two]natrsquo = lsquo0n1rsquo

Table 4 Cast to lsquointrsquo

From Operation Examples

bool bit value lsquo[false]intrsquo = lsquo0i0rsquolsquo[true]intrsquo = lsquo0i1rsquo

string parse decimal lsquo[123]intrsquo = lsquo0i123rsquolsquo[-123]intrsquo = lsquo-0i123rsquolsquo[~123]intrsquo = lsquo-0i123rsquolsquo[]intrsquo is undefinedlsquo[hello]intrsquo is undefined

nat value lsquo[0n123]intrsquo = lsquo0i123rsquoint identity lsquo[0i123]intrsquo = lsquo0i123rsquobool list value lsquo[0s11]intrsquo = lsquo0i3rsquobits(middot) signed value lsquo[123`8]intrsquo = lsquo0i123rsquo

lsquo[130`8]intrsquo = lsquo-0i126rsquoEnum enumerate lsquo[One]intrsquo = lsquo0i0rsquo

31

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

Table 5 Cast to lsquobit-stringrsquo

From Operation Examples

bool bit value lsquo[false]bool listrsquo = lsquo0s0rsquolsquo[true]bool listrsquo = lsquo0s1rsquo

string parse binary lsquo[101]bool listrsquo = lsquo0s101rsquolsquo[123]bool listrsquo is undefined

nat value lsquo[0n123]bool listrsquo = lsquo0s1111011rsquoint value lsquo[0i123]bool listrsquo = lsquo0s1111011rsquo

lsquo[-0i1]bool listrsquo is undefinedbool list identity lsquo[0s11]bool listrsquo = lsquo0s11rsquobits(middot) unsigned value lsquo[123`8]bool listrsquo = lsquo0s01111011rsquoEnum enumerate lsquo[One]bool listrsquo = lsquo0s0rsquo

Table 6 Cast to lsquobits(n)rsquo

From Operation Examples

bool bit value lsquo[false]`8rsquo = lsquo0x0`8rsquolsquo[true]`8rsquo = lsquo0x1`8rsquo

string parse hexadecimal lsquo[8B]`8rsquo = lsquo0x8B`8rsquolsquo[-A]`8rsquo = lsquo0xF6`8rsquolsquo[100]`8rsquo is undefined (too big)

nat unsigned value (mod 2n) lsquo[0n123]`8rsquo = lsquo0x7B`8rsquolsquo[0n256]`8rsquo = lsquo0x0`8rsquo

int signed value (mod 2n) lsquo[0i123]`8rsquo = lsquo0x7B`8rsquolsquo[0i256]`8rsquo = lsquo0x0`8rsquolsquo[-0i1]`8rsquo = lsquo0xFF`8rsquolsquo[-0i133]`8rsquo = lsquo0x7B`8rsquo

bool list unsigned value (mod 2n) lsquo[0s1111]`8rsquo = lsquo0xF`8rsquolsquo[0s1000000001]`8rsquo = lsquo0x1`8rsquo

bits(p) identity zero extend (p le n) lsquo[0x81`8]`10rsquo = lsquo0x81`10rsquotruncate (n lt p) lsquo[0xFF0`12]`8rsquo = lsquo0xF0`8rsquo

Enum enumerate lsquo[One]`8rsquo = lsquo0s0rsquolsquo[Three]`1rsquo is undefined (too big)

32

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

Table 7 Cast to lsquoEnumrsquo

From Operation Examples

bool type errorstring parse lsquo[One]Enumrsquo = lsquoOnersquo

lsquo[hello]Enumrsquo is undefinednat select lsquo[0n1]Enumrsquo = lsquoTworsquo

lsquo[0n3]Enumrsquo is undefinedint select lsquo[0i1]Enumrsquo = lsquoTworsquo

lsquo[0i3]Enumrsquo is undefinedlsquo[-0i1]Enumrsquo is undefined

bool list select lsquo[0s1]`8rsquo = lsquoTworsquolsquo[0s11]Enumrsquo is undefined

bits(middot) select lsquo[1`8]Enumrsquo = lsquoTworsquolsquo[3`8]Enumrsquo is undefined

Enum identity lsquo[One]Enumrsquo = lsquoOnersquoEnum2 select lsquo[Four]Enumrsquo = lsquoOnersquo

lsquo[Seven]Enumrsquo is undefined

33

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

B SyntaxReserved wordsThe names of all primitive types operators and constants are reserved see Appendix A Otherreserved words are

assign case clear component construct declare define do else exception forforeach if list match nothing pattern patterns record register return set thentype var when RAO RAZ UNK UNKNOWN

CommentsInline comments start with lsquo--rsquo Block comments are delimited by lsquo-rsquo and lsquo-rsquo and can benested All commented code is ignored (not parsed)

Number literalsIn the following no white-space is permitted

⟨bin⟩ = lsquo0rsquo | lsquo1rsquo

⟨dec⟩ = ⟨bin⟩ | lsquo2rsquo | lsquo3rsquo | lsquo4rsquo | lsquo5rsquo | lsquo6rsquo | lsquo7rsquo | lsquo8rsquo | lsquo9rsquo

⟨hex⟩ = ⟨dec⟩ | lsquoarsquo | lsquobrsquo | lsquocrsquo | lsquodrsquo | lsquoersquo | lsquofrsquo | lsquoArsquo | lsquoBrsquo | lsquoCrsquo | lsquoDrsquo | lsquoErsquo | lsquoFrsquo

⟨binary⟩ = ⟨bin⟩ | ⟨bin⟩ ⟨binary⟩ | ⟨bin⟩ lsquo_rsquo ⟨binary⟩

⟨decimal⟩ = ⟨dec⟩ | ⟨dec⟩ ⟨decimal⟩ | ⟨dec⟩ lsquo_rsquo ⟨decimal⟩

⟨hexadecimal⟩ = ⟨hex⟩ | ⟨hex⟩ ⟨hexadecimal⟩ | ⟨hex⟩ lsquo_rsquo ⟨hexadecimal⟩

⟨number⟩ = ⟨decimal⟩ | lsquo0brsquo ⟨binary⟩ | lsquo0drsquo ⟨decimal⟩ | lsquo0xrsquo ⟨hexadecimal⟩| lsquo0nrsquo ⟨decimal⟩ | lsquo0nbrsquo ⟨binary⟩ | lsquo0ndrsquo ⟨decimal⟩ | lsquo0nxrsquo ⟨hexadecimal⟩

⟨numeric⟩ = ⟨number⟩| lsquo0irsquo ⟨decimal⟩ | lsquo0ibrsquo ⟨binary⟩ | lsquo0idrsquo ⟨decimal⟩ | lsquo0ixrsquo ⟨hexadecimal⟩| lsquo0srsquo ⟨decimal⟩ | lsquo0sbrsquo ⟨binary⟩ | lsquo0sdrsquo ⟨decimal⟩ | lsquo0sxrsquo ⟨hexadecimal⟩| lsquo0wrsquo ⟨decimal⟩ | lsquo0wbrsquo ⟨binary⟩ | lsquo0wdrsquo ⟨decimal⟩ | lsquo0wxrsquo ⟨hexadecimal⟩

Identifiers⟨alpha⟩ = lsquoarsquo lsquozrsquo | lsquoArsquo lsquoZrsquo

⟨alphanum⟩ = ⟨alpha⟩ | ⟨dec⟩ | lsquo_rsquo

⟨alphanums⟩ = ⟨alphanum⟩ | ⟨alphanum⟩ ⟨alphanums⟩

⟨name⟩ = ⟨alpha⟩ | ⟨alpha⟩⟨alphanums⟩

34

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

TypesIn the following white-space is permitted

⟨type⟩ = ⟨tuple-type⟩ | ⟨tuple-type⟩ lsquo-gtrsquo ⟨tuple-type⟩

⟨tuple-type⟩ = ⟨base-type⟩ | ⟨base-type⟩ lsquorsquo ⟨tuple-type⟩

⟨base-type⟩ = lsquounitrsquo | lsquoboolrsquo | lsquostringrsquo | lsquonatrsquo | lsquointrsquo| lsquobitsrsquo lsquo(rsquo ⟨bits-type⟩ lsquo)rsquo| ⟨base-type⟩ lsquolistrsquo| ⟨base-type⟩ lsquooptionrsquo| ⟨base-type⟩ lsquosetrsquo| ⟨name⟩| lsquo(rsquo ⟨type⟩ lsquo)rsquo

⟨bits-type⟩ = ⟨name⟩ | ⟨number⟩

⟨annotation⟩ = lsquorsquo ⟨type⟩ | lsquo`rsquo ⟨bits-type⟩

⟨a-name⟩ = ⟨name⟩ ⟨annotation⟩

⟨opt-a-name⟩ = ⟨name⟩ | ⟨a-name⟩

Specifications⟨specification⟩ = ⟨declaration⟩ | ⟨declaration⟩ ⟨specification⟩

⟨declaration⟩ = ⟨definition⟩| lsquotypersquo ⟨name⟩ lsquo=rsquo ⟨type⟩| lsquoconstructrsquo ⟨name⟩ lsquorsquo ⟨constructs⟩ lsquorsquo| lsquorecordrsquo ⟨name⟩ lsquorsquo ⟨arguments⟩ lsquorsquo| lsquoregisterrsquo ⟨a-name⟩ lsquorsquo ⟨fields⟩ lsquorsquo| lsquodeclarersquo ⟨globals⟩| lsquoexceptionrsquo ⟨opt-a-name⟩| lsquopatternrsquo ⟨hints⟩| lsquoclearrsquo lsquopatternrsquo ⟨name-list⟩| lsquoclearrsquo lsquopatternsrsquo

⟨constructs⟩ = ⟨opt-a-name⟩| ⟨opt-a-name⟩ ⟨constructs⟩| ⟨opt-a-name⟩ lsquorsquo ⟨constructs⟩

⟨globals⟩ = ⟨a-name⟩ | lsquorsquo ⟨arguments⟩ lsquorsquo

⟨arguments⟩ = ⟨a-name⟩| ⟨a-name⟩ ⟨arguments⟩| ⟨a-name⟩ lsquorsquo ⟨arguments⟩

⟨hints⟩ = ⟨hint⟩ | lsquorsquo ⟨hint-sequence⟩ lsquorsquo

⟨hint-sequence⟩ = ⟨hint⟩ | ⟨hint⟩ ⟨hint-sequence⟩ | ⟨hint⟩ lsquorsquo ⟨hint-sequence⟩

35

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

⟨hint⟩ = ⟨names⟩ ⟨annotation⟩

⟨names⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨names⟩ | ⟨name⟩ ⟨names⟩

⟨name-list⟩ = ⟨name⟩ | ⟨name⟩ lsquorsquo ⟨name-list⟩

Definitions⟨definition⟩ = lsquodefinersquo ⟨define⟩

| lsquocomponentrsquo ⟨component⟩| ⟨function⟩

⟨define⟩ = ⟨ast⟩ ⟨define-sig⟩ lsquo=rsquo ⟨block⟩

⟨ast⟩ = ⟨name⟩ | ⟨name⟩ lsquogtrsquo ⟨ast⟩

⟨component⟩ = ⟨name⟩ ⟨component-sig⟩ lsquorsquo lsquovaluersquo lsquo=rsquo ⟨block⟩ lsquoassignrsquo ⟨name⟩ lsquo=rsquo ⟨block⟩ lsquorsquo

⟨function⟩ = ⟨type⟩ ⟨name⟩ ⟨function-sig⟩ lsquo=rsquo ⟨block⟩

⟨define-sig⟩ = ⟨single-constraint⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨single-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨single-constraint⟩

⟨function-sig⟩ = ⟨constraints⟩| lsquo(rsquo lsquo)rsquo| lsquo(rsquo lsquo)rsquo ⟨constraints⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨constraints⟩

⟨component-sig⟩ = ⟨type-constraint⟩| lsquo(rsquo lsquo)rsquo ⟨type-constraint⟩| lsquo(rsquo ⟨args⟩ lsquo)rsquo ⟨type-constraint⟩

⟨type-constraint⟩ = lsquorsquo ⟨type⟩| lsquorsquo ⟨type⟩ ⟨constraints⟩

⟨args⟩ = ⟨a-name⟩ | ⟨a-name⟩ lsquorsquo ⟨args⟩

Blocks and Statements⟨block⟩ = ⟨statement⟩

| lsquorsquo ⟨sequence⟩ lsquorsquo ⟨return⟩ lsquorsquo| ⟨return⟩

⟨statement⟩ = lsquorsquo ⟨sequence⟩ lsquorsquo | ⟨command⟩

⟨return⟩ = lsquoreturnrsquo ⟨expression⟩ | ⟨expression⟩

⟨sequence⟩ = ⟨command⟩ | ⟨command⟩ lsquorsquo ⟨sequence⟩

36

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

⟨command⟩ = lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨block⟩ lsquoelsersquo ⟨block⟩| lsquowhenrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨cases⟩ lsquorsquo| lsquoforrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquorsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquoforeachrsquo ⟨name⟩ lsquoinrsquo ⟨expression⟩ lsquodorsquo ⟨statement⟩| lsquonothingrsquo| lsquovarrsquo ⟨name⟩| lsquovarrsquo ⟨name⟩ lsquo=rsquo ⟨expression⟩| ⟨reference⟩ lsquolt-rsquo ⟨expression⟩| ⟨tuple⟩ lsquo=rsquo ⟨expression⟩

⟨tuple⟩ = ⟨tuple-literal⟩ | ⟨tuple-literal⟩ lsquorsquo ⟨tuple⟩

⟨tuple-literal⟩ = ⟨tuple-lit⟩ | ⟨tuple-lit⟩ ⟨annotation⟩

⟨tuple-lit⟩ = ⟨name⟩ | lsquo_rsquo | lsquo(rsquo ⟨tuple⟩ lsquo)rsquo

⟨cases⟩ = ⟨case⟩ | ⟨case⟩ ⟨cases⟩

⟨case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨block⟩

⟨patterns⟩ = ⟨pattern⟩ | ⟨pattern⟩ lsquoorrsquo ⟨patterns⟩

Expressions⟨expression⟩ = ⟨expr⟩ | ⟨expr⟩ ⟨binary-op⟩ ⟨expression⟩

⟨expr⟩ = ⟨clause⟩ | ⟨clause⟩ ⟨annotation⟩

⟨binary-op⟩ = lsquorsquo | lsquoorrsquo | lsquoandrsquo | lsquo==rsquo | lsquo=rsquo | lsquoltgtrsquo | lsquoltrsquo | lsquolt+rsquo | lsquolt=rsquo | lsquolt=+rsquo | lsquogtrsquo | lsquogt+rsquo | lsquogt=rsquo | lsquogt=+rsquo |lsquoinrsquo | lsquonotinrsquo | lsquoinsertrsquo | lsquorsquo | lsquorsquo | lsquo-rsquo | lsquo+rsquo | lsquo||rsquo | lsquorsquo | lsquorsquo | lsquoquotrsquo | lsquoremrsquo | lsquodivrsquo| lsquomodrsquo | lsquoampamprsquo | lsquoltltrsquo | lsquogtgtrsquo | lsquogtgt+rsquo | lsquogtgtrsquo | lsquoltltrsquo | lsquo^rsquo | lsquorsquo

⟨clause⟩ = ⟨unary-op⟩ ⟨expression⟩| ⟨reference⟩| ⟨expression-literal⟩| lsquorsquo ⟨name⟩| lsquorsquo ⟨name⟩ ⟨expression-literal⟩| lsquoifrsquo ⟨expression⟩ lsquothenrsquo ⟨expression⟩ lsquoelsersquo ⟨expression⟩| lsquomatchrsquo ⟨expression⟩ lsquorsquo ⟨expression-cases⟩ lsquorsquo| lsquosetrsquo lsquorsquo ⟨expression⟩ lsquorsquo| lsquolistrsquo lsquorsquo ⟨expression⟩ lsquorsquo

⟨unary-op⟩ = lsquonotrsquo | lsquorsquo | lsquo-rsquo | lsquo~rsquo

⟨expression-literal⟩ = lsquo(rsquo lsquo)rsquo| lsquo(rsquo ⟨expression⟩ lsquo)rsquo| lsquo[rsquo ⟨expression⟩ lsquo]rsquo

37

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

| lsquorsquo ⟨binary⟩ lsquorsquo| lsquorsquo ⟨string⟩ lsquorsquo| lsquorsquo ⟨character⟩ lsquorsquo| ⟨numeric⟩ | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

⟨expression-cases⟩ = ⟨expression-case⟩ | ⟨expression-case⟩ ⟨expression-cases⟩

⟨expression-case⟩ = lsquocasersquo ⟨patterns⟩ lsquo=gtrsquo ⟨expression⟩

⟨reference⟩ = lsquoamprsquo ⟨entity⟩| lsquoamprsquo ⟨entity⟩ ⟨index⟩| ⟨dotted⟩| ⟨dotted⟩ ⟨index⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩| ⟨dotted⟩ lsquorsquo lsquoamprsquo ⟨entity⟩ ⟨index⟩

⟨dotted⟩ = ⟨entity⟩ | ⟨entity⟩ lsquorsquo ⟨dotted⟩

⟨entity⟩ = ⟨name⟩| ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨expression⟩ lsquo)rsquo

⟨index⟩ = lsquoltrsquo ⟨expression⟩ lsquogtrsquo

Patterns⟨pattern⟩ = ⟨pat⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩ | ⟨pat⟩ lsquorsquo ⟨pattern⟩

⟨pat⟩ = ⟨pattern-literal⟩ | ⟨pattern-literal⟩ ⟨annotation⟩

⟨pattern-literal⟩ = ⟨name⟩ lsquo(rsquo lsquo)rsquo| ⟨name⟩ lsquo(rsquo ⟨pattern⟩ lsquo)rsquo| ⟨pattern-lit⟩| ⟨bit-pattern⟩| lsquo-rsquo ⟨number⟩| lsquo(rsquo ⟨pattern⟩ lsquo)rsquo

⟨pattern-lit⟩ = ⟨name⟩ | ⟨number⟩ | lsquo_rsquo | lsquotruersquo | lsquofalsersquo | lsquoUNKNOWNrsquo

Bit patterns⟨bit-pattern⟩ = lsquorsquo ⟨bit-pat⟩ lsquorsquo

⟨bit-pat⟩ = ⟨bit-pattern-lit⟩| ⟨bit-pattern-lit⟩ ⟨bit-pat⟩| ⟨bit-pattern-lit⟩ lsquorsquo ⟨bit-pat⟩

⟨bit-pattern-lit⟩ = ⟨pattern-lit⟩| ⟨pattern-lit⟩ lsquo`rsquo ⟨bits-type⟩| lsquo(rsquo ⟨binary⟩ lsquo)rsquo

38

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax

Constraints⟨constraints⟩ = lsquowithrsquo ⟨constraint-list⟩

⟨single-constraint⟩ = lsquowithrsquo ⟨name⟩ lsquoinrsquo ⟨number-list⟩

⟨constraint-list⟩ = ⟨constraint⟩ | ⟨constraint⟩ lsquoandrsquo ⟨constraint-list⟩

⟨constraint⟩ = ⟨name⟩ lsquoinrsquo ⟨number-set⟩ | ⟨name⟩ ⟨ordering⟩ ⟨number⟩

⟨ordering⟩ = lsquoltrsquo | lsquogtrsquo | lsquolt=rsquo | lsquogt=rsquo

⟨number-list⟩ = ⟨number⟩ | ⟨number⟩ lsquorsquo ⟨number-list⟩

⟨number-set⟩ = ⟨range⟩ | ⟨range⟩ lsquorsquo ⟨number-set⟩

⟨range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩ | ⟨number⟩ lsquorsquo

Register specifications⟨fields⟩ = ⟨field⟩ | ⟨field⟩ ⟨fields⟩ | ⟨field⟩ lsquorsquo ⟨fields⟩

⟨field⟩ = ⟨bit-ranges⟩ lsquorsquo ⟨field-name⟩

⟨bit-ranges⟩ = ⟨bit-range⟩ | ⟨bit-range⟩ lsquorsquo ⟨bit-ranges⟩

⟨bit-range⟩ = ⟨number⟩ | ⟨number⟩ lsquo-rsquo ⟨number⟩

⟨field-name⟩ = lsquoUNKrsquo | lsquoRAZrsquo | lsquoRAOrsquo | ⟨name⟩

39

  • Language Features
    • Commenting
    • Primitive Types
    • Literals
    • Global State
    • Tuples
    • Maps
    • Sum Types
    • Records
    • Registers
    • Polymorphic Types
    • Statements and Expressions
    • Defining Constants and Operations
    • Components
    • Recursion
    • Instruction Set Definitions
      • Tutorial
      • Primitive Types and Operations
        • Unit
        • Bool
        • Nat
        • Int
        • Bit-vectors
        • Bit-strings
        • Characters and Strings
        • Floating-point
        • Miscellaneous operations
          • Syntax