// Author(s):   Jonathan Nelisse
// 11 March 2010
//
// This document describes the internal format of the CSP language:
// - <Name> is an arbitrary non-empty string [a-zA-Z][a-zA-Z0-9_]*'*
//   excluding the keywords:
//     head tail if then else length card true false and or not
//     null elem member empty concat union inter diff Union Inter
//     set Set Seq extensions productions let within Int Bool
//     nametype datatype subtype channel Events STOP SKIP CHAOS
//     external transparant normal sbsim tau_loop_factor diamond
//     model_compress explicate assert deterministic deadlock free
//     divergence free T F FD print attribute embed module
// - <Number> is a string of the format '"0"|([1-9][0-9]*)'
// - the alphabetical strings within angular brackets are non-terminals
//   that represent all possible branches of their productions
// - for non-terminal N, N*/N+ represents an ATermList with zero/one or more N's
// - each c(a_0, ..., a_n), where c is an alphabetical string, represents an
//   ATermAppl with c as its unquoted head and a_0, ..., a_n as its arguments


// FDRSpec
//-------------

// FDR specification
<FDRSpec>   ::= FDRSpec(<Defn>*)

// Definition
<Defn>      ::= Assign(<Any>, <Any>)
              | Channel(<Name>+, <Type>)
              | SimpleChannel(<Name>+)
              | NameType(<Name>, <Type>)
              | DataType(<Name>, <VarType>+)
              | SubType(<Name>, <VarType>+)
              | External(<Name>+)
              | Transparent(<TrName>+)
              | Assert(<Check>)
              | Print(<Expr>)
              | Include(<FileName>)

// Types
<VarType>   ::= SimpleBranch(<Name>)
              | Branch(<Name>, <Type>)

<Type>      ::= TypeProduct(<Type>, <Type>)
              | TypeTuple(<Type>+)
              | TypeSet(<Set>)
              | SimpleTypeName(<Name>)
              | TypeName(<Name>, <Type>+)

// Assertions
<Check>     ::= BCheck(<Bool>)
              | RCheck(<Proc>, <Proc>, <Refined>)
              | TCheck(<Proc>, <Test>)
              | NotCheck(<Check>)

<Refined>   ::= Refined(<Model>)

<Model>     ::= Nil
              | T
              | <FailureModel>

<FailureModel>  ::= F
                  | FD

<Test>      ::= <TestType>
              | Test(<TestType>, <FailureModel>)
              | divergence_free

<TestType>  ::= deterministic
              | deadlock_free
              | livelock_free

// Transparent
<TrName>    ::= normal
              | normalise
              | normalize
              | sbsim
              | tau_loop_factor
              | diamond
              | model_compress
              | explicate

// Include
<FileName>  ::= FileName(<Name>+)

// Any expression or process
<Any>       ::= Expr(<Expr>)
              | Proc(<Proc>)


// Expressions
//-------------

// Expression
<Expr>      ::= <Numb>
              | <Bool>
              | <Set>
              | <Seq>
              | <Tuple>
              | <Dotted>
              | <Lambda>

// Numeric expression
<Numb>      ::= <Common>
              | Number(<Number>)
              | Card(<Set>)
              | Length(<Seq>)
              | Plus(<Numb>, <Numb>)
              | Minus(<Numb>, <Numb>)
              | Times(<Numb>, <Numb>)
              | Div(<Numb>, <Numb>)
              | Mod(<Numb>, <Numb>)
              | Min(<Numb>)

// Boolean expression
<Bool>      ::= <Common>
              | true
              | false
              | And(<Bool>, <Bool>)
              | Or(<Bool>, <Bool>)
              | Not(<Bool>)
              | Null(<Seq>)
              | Elem(<Expr>, <Seq>)
              | Member(<Expr>, <Set>)
              | Empty(<Set>)
              | Equal(<Expr>, <Expr>)
              | NotEqual(<Expr>, <Expr>)
              | Less(<Expr>, <Expr>)
              | LessOrEqual(<Expr>, <Expr>)
              | Greater(<Expr>, <Expr>)
              | GreaterOrEqual(<Expr>, <Expr>)

// Set expression
<Set>       ::= <Common>
              | <Targ>
              | ChanSet(<Targ>)
              | union(<Set>, <Set>)
              | inter(<Set>, <Set>)
              | diff(<Set>, <Set>)
              | Union(<Set>)
              | Inter(<Set>)
              | set(<Seq>)
              | Seq(<Set>)
              | Set(<Set>)
              | extensions(<Expr>)
              | productions(<Expr>)

// Sequence expression
<Seq>       ::= <Common>
              | <Targ>
              | Cat(<Seq>, <Seq>)
              | Concat(<Seq>)
              | Head(<Seq>)
              | Tail(<Seq>)

// Expression list
<Exprs> ::= Exprs(<Expr>+)

// Set/Sequence arguments
<Targ> ::= Nil
             | <Exprs>
             | ClosedRange(<Numb>, <Numb>)
             | OpenRange(<Numb>)
             | Compr(<Expr>, <Comprehension>+)

// Comprehension
<Comprehension> ::= Nil
                  | BComprehension(<Bool>)
                  | EComprehension(<Expr>, <Expr>)

// Tuple expression
<Tuple>     ::= <Common>
              | <Exprs>

// Dotted expression
<Dotted>    ::= <Common>
              | Dot(<Expr>, <Expr>)

// Lambda expression
<Lambda>    ::= <Common>
              | LambdaExpr(<Expr>+, <Any>)

// Common expression
<Common>    ::= Conditional(<Bool>, <Any>, <Any>)
              | Name(<Name>)
              | LambdaAppl(<Lambda>, <Expr>+)
              | LocalDef(<Defn>+, <Any>)
              | Bracketed(<Any>)
              | Pattern(<Any>, <Any>)


// Processes
//-------------

// Process expression
<Proc>      ::= <Common>
              | STOP
              | SKIP
              | CHAOS(<Set>)
              | Prefix(<Dotted>, <Field>*, <Proc>)
              | ExternalChoice(<Proc>, <Proc>)
              | InternalChoice(<Proc>, <Proc>)
              | SequentialComposition(<Proc>, <Proc>)
              | Interrupt(<Proc>, <Proc>)
              | Hiding(<Proc>, <Set>)
              | Rename(<Proc>, <Renaming>)
              | Interleave(<Proc>, <Proc>)
              | Sharing(<Proc>, <Proc>, <Set>)
              | AlphaParallel(<Proc>, <Proc>, <Set>, <Set>)
              | RepExternalChoice(<SetGen>, <Proc>)
              | RepInternalChoice(<SetGen>, <Proc>)
              | RepSequentialComposition(<SeqGen>, <Proc>)
              | RepInterleave(<SetGen>, <Proc>)
              | RepSharing(<SetGen>, <Proc>, <Set>)
              | RepAlphaParallel(<SetGen>, <Proc>, <Set>)
              | UntimedTimeOut(<Proc>, <Proc>)
              | BoolGuard(<Bool>, <Proc>)
              | LinkedParallel(<Proc>, <Proc>, <LinkPar>)
              | RepLinkedParallel(<SeqGen>, <Proc>, <LinkPar>)

// Input/Output field
<Field>     ::= SimpleInput(<Expr>)
              | Input(<Expr>, <Set>)
              | Output(<Expr>)

// Generators
<SetGen> ::= SetGen(<Expr>, <Set>)

<SeqGen> ::= SeqGen(<Expr>, <Seq>)

// Renaming
<Renaming>  ::= Maps(<Map>+)
              | MapsGens(<Map>+, <Comprehension>+)

<Map>       ::= Map(<Dotted>, <Dotted>)

// Linking
<LinkPar>   ::= Links(<Link>+)
              | LinksGens(<Link>+, <Comprehension>+)

<Link>      ::= Link(<Dotted>, <Dotted>)
