
(* this now handles the Reward Language too *)

(* e.g.

   reward name = formula => expression

   attachment name = rewspec => (processname, integer)

*)


fun prepl (Pepa.CONSTS(i,c,c')) p =
          Pepa.CONSTS(i,c,(prepl c' p))
  | prepl _ p = p;

fun member x [] = false
  | member x (h::t) = if (x = h) then true else (member x t)

fun uniqify [] = []
  | uniqify (h::t) = if (member h t) then (uniqify t) else (h::(uniqify t))

fun listrem x [] = []
  | listrem x (h::t) = if (x = h) then (listrem x t) else (h::(listrem x t))

fun curry f a b = f(a,b);
fun uncurry f (a,b) = f a b;

%%

%eop PEOF

%pos int

%left      LCOOP PAR UNION
%left      SETMINUS
%nonassoc  HIDE MULT
%left      SUM
%nonassoc  MINUS
%nonassoc  DOT

%term COMMA | DOT | TOP | LPAREN | RPAREN | SEMI
 | EQUALS | PAR | LCOOP | RCOOP | MINUS | MULT | SUM | HIDE | HASH
 | PERC | EXP | NORM | UNIF | LSET | RSET | UNION | SETMINUS
 | LAND | LOR | LNOT | NABLA | DELTA | MTT | MFF | LSQUARE | RSQUARE
 | REWARD | ATTACHMENT | ARROW | RATE
 | PEOF | STRN of string | NUMB of real | INTNUMB of int

%nonterm Defns of Pepa.Component | Proc of Pepa.Component | Process of 
Pepa.Component | Procdefns of Pepa.Component | Procdefn of
(Pepa.Identifier * Pepa.Component) | Identdefn of unit | Identdefns of 
unit | Activity of (Pepa.Identifier * Expressions.Aexp) | Anaction of
Pepa.Identifier | Actions of (Pepa.Identifier list) | Actionset of
(Pepa.Identifier list) | Actionlist of (Pepa.Identifier list) |
Actionlisttwo of (Pepa.Identifier list) | Coopset of (Pepa.Identifier
list) | Arithexp of Expressions.Aexp | Rewexp of Expressions.Aexp |
Real of real | Integer of int | 
Rate of Expressions.Aexp | Rewspecdefn of unit | Attachmentdefn of unit | Form of RewLang.Formula

%name Pepa

%verbose

%%

Process:
    Defns Proc PEOF
      ( prepl Defns Proc )

Defns:
    Defns HASH Procdefn SEMI
      ( let val (id,p) = Procdefn
        in
           Pepa.CONSTS(id, p, Defns)
        end
      )
  |
    Defns PERC Identdefn SEMI
      ( Defns )
  |
    Defns PERC Rewspecdefn SEMI
      ( Defns )
  |
    Defns PERC Attachmentdefn SEMI
      ( (RewLang.hasAttachments := true;
         Defns) )
  |
      ( Pepa.VAR(HashTable.hash("dummy")) )


Real:
    NUMB
      ( NUMB )

Integer:
    INTNUMB
      ( INTNUMB )

Procdefn:
    STRN EQUALS Proc
      ( (HashTable.hash(STRN), Proc) )

Rewspecdefn:
    REWARD STRN EQUALS Form ARROW Rewexp
      ( (Identifiers.addRewSpecID (Identifiers.makeID STRN)
                                  (RewLang.makeRewSpec(Form, Rewexp));
         ()) )	

Attachmentdefn:
    ATTACHMENT STRN EQUALS STRN ARROW LPAREN Proc COMMA Integer RPAREN
      ( (Identifiers.addAttachmentID (Identifiers.makeID STRN1)
                      (RewLang.makeAttachment(
                        (Identifiers.getRewSpec(Identifiers.makeID STRN2)),
                        (Proc, Integer)));
         ()) )	

Identdefn:
    STRN EQUALS Actionset
      ( (Identifiers.addSetID (Identifiers.makeID STRN) Actionset;
         ()) )
  | STRN EQUALS Arithexp
      ( (Expressions.addExpID (Identifiers.makeID STRN) Arithexp;
         ()) )

Anaction:
    STRN
      ( HashTable.hash(STRN) )

Activity:
    LPAREN STRN COMMA Rate RPAREN
      ( (HashTable.hash(STRN), Rate) )


Rate:
      Arithexp
      ( Expressions.subForIDs(Arithexp) )

Coopset:
    LCOOP Actions RCOOP
      ( (Actions) )
  | LCOOP RCOOP
      ( ([]:Pepa.Identifier list) )
  | PAR
      ( ([]:Pepa.Identifier list) )


Actions:
    Actionlist
      ( Actionlist )
  | Actionset
      ( Actionset )

Arithexp:
    STRN
      ( Expressions.IDENT STRN )
  | LPAREN Arithexp RPAREN
      ( Arithexp )
  | Arithexp SUM Arithexp
      ( Expressions.PLUS(Arithexp1, Arithexp2) )
  | Arithexp MINUS Arithexp
      ( Expressions.DIFF(Arithexp1, Arithexp2) )
  | Arithexp MULT Arithexp
      ( Expressions.PROD(Arithexp1, Arithexp2) )
  | Arithexp HIDE Arithexp
      ( Expressions.QUOT(Arithexp1, Arithexp2) )
  | TOP
      ( Expressions.TOP )
  | Real
      ( Expressions.NUM(Real) )
  | Integer
      ( Expressions.INTNUM(Integer) )

Rewexp:
    RATE Anaction RPAREN
      ( Expressions.RATE(Anaction) )
  | Arithexp
      ( Arithexp )


Actionset:
    STRN
      ( Identifiers.getSet (Identifiers.makeID STRN)
          handle _ => [HashTable.hash(STRN)]
      )
  | LSET Actionlisttwo RSET
      ( Actionlisttwo)
  | LPAREN Actionset RPAREN
      ( Actionset )
  | Actionset UNION Actionset
      ( uniqify(Actionset1 @ Actionset2) )
  | Actionset SETMINUS Actionset
      ( foldl (uncurry listrem) Actionset2 Actionset1 )

Actionlist:
    Actionlisttwo COMMA Anaction
      ( Anaction::Actionlisttwo )

Actionlisttwo:
    Actionlisttwo COMMA Anaction
      ( Anaction::Actionlisttwo )
  | Anaction
      ( [Anaction] )

Proc:
    Activity DOT Proc
      ( Pepa.PREFIX(Activity, Proc) )
  | Proc SUM Proc
      ( Pepa.CHOICE(Proc1, Proc2) )
  | Proc Coopset Proc
      ( Pepa.COOP([Proc1, Proc2], Coopset) )
  | Proc HIDE Actionset
      ( Pepa.HIDING(Proc, Actionset) )
  | LPAREN Proc RPAREN
      ( Proc )
  | STRN
      ( Pepa.VAR(HashTable.hash(STRN)) )


Form:
    DELTA Anaction RSET
      ( RewLang.Delta(Anaction) )
  | NABLA Anaction RSET
      ( RewLang.Nabla(Anaction) )
  | Form LAND Form
      ( RewLang.And(Form1, Form2) )
  | Form LOR Form
      ( RewLang.Or(Form1, Form2) )
  | LNOT Form
      ( RewLang.Not(Form) )
  | MTT 
      ( RewLang.Mtt )
  | MFF 
      ( RewLang.Mff )
  | LCOOP Anaction COMMA Arithexp RCOOP Form
      ( RewLang.Dia(Anaction, Arithexp, Form) )
  | LSQUARE Anaction COMMA Arithexp RSQUARE Form
      ( RewLang.Box(Anaction, Arithexp, Form) )
  | LPAREN Form RPAREN
      ( Form )





