Identifiers
-----------

letter 	::=	 a … z ∣   A … Z  
 
digit 	::=	 0 … 9  
 
id 	::=	 letter  { letter ∣  digit ∣  _ ∣  . ∣  - } 

predefined identifiers: 

  . id (identity relation)
  . po (program order)
  . addr (address dependency)
  . data (data dependency)
  . ctrl (ctrl dependency)
  . loc (relation between events having the same location)
  . ext (relation between events on different threads)
  . rf (read-from)
  . co (coherence)
  . W (set of writes)
  . R (set of reads)
  . F (set of fences)
  . I (set of init writes)

Expressions
-----------

expr 	::=	 0  
 	∣	 id
 	∣	 expr * ∣  expr + ∣  expr ? ∣  expr ^-1  
 	∣	 expr | expr ∣  expr ; expr ∣  expr \ expr ∣  expr & expr
 	∣	 expr ++ expr                 # add elt to set
 	∣	 expr expr                    # function application
 	∣	 fun  pat ->  expr  
 	∣	 let  binding  { and  binding }  in  expr  
 	∣	 let  rec  binding  { and  binding }  in  expr  
 	∣	 ( expr ) ∣   begin  expr  end  
        |        'id  #tag
 	∣	 '{' '}' | '{' expr { , expr } '}' # explicit set
 	∣	 () | ( expr { , expr } )     # tuples
        |        match expr with {} -> expr || id ++ id -> expr end # set matching    
        |        match expr with
                   'id -> expr { || 'id -> expr } [ _ -> expr ] # tag matching

pat     ::=
        ∣ id
        | ( params )

params 	::=	 є  
 	∣	 id  { ,  id }  
 
binding 	::=	 valbinding ∣  funbinding  
 
valbinding 	::=	 pat  =  expr  
 
funbinding 	::=	 id  pat  =  expr  

instruction 	::=	 let  binding  { and  binding }  
 	∣	 let  rec  binding  { and  binding }  
 	∣	 [ flag ] check  expr  [ as  id]  
 	∣	 procedure  id  (  params  )  =  { instruction }  END  
 	∣	 call  id  expr [ as id ]
 	∣	 show  expr  as  id  
 	∣	 show  id  { ,  id }  
 	∣	 unshow  id  { ,  id }  
 	∣	 include string  

    	∣	 with id from expr                          # choice ??
    	∣	 forall id in expr do { instruction } end   # for loop
    	∣	 enum id = 'id { || 'id }                   # enum definition

check 	::=	 acyclic ∣  irreflexive ∣  empty
        ∣ ~acyclic ∣  ~irreflexive ∣  ~empty

Events, scopes and regions (Bell constructs )
--------------------------

The following are bell specific (ignored by cat)

event_sets        ::=  events TYPE[TAGS1,..,TAGSN]

  Define legal instruction (events) annotations where:
   - TYPE is R,W,F or RMW.
   - TAGSi is a set of tags.

The following definitions have additional, specific, bell interpretation.
enum regions = 'tag1 || ... || 'tagN

enum scopes = 'tag1 || ... || 'tagN

let wider(s) = ...
  The wider function defines the scope hierarchy by its parent function that
  associate the tag (of enum scopes) of the parent to the tag of a scope

let narrower = ..
  The narrower function defines the scope hierarchy by its children function.
  Notice that narrower may return a set of tags.


