[/] [trunk/] [src/] [maketest/] [sel_trans.sig] - Rev 44

(* $Id: sel_trans.sig 44 2008-05-10 11:23:01Z tbourke $ *)

signature SEL_TRANS = sig

  type expr      = Expression.expr
   and ty        = Expression.ty
   and symbol    = Atom.atom
   and symbolset = AtomSet.set

  exception NonSimpleSelectIndex of expr
  exception BadChannelIndex of {id: symbol, badty: ty, goodty: ty}
  exception BadSubscriptCount

  datatype t = SelTrans of {selectids:  (symbol * ty) list,
                            guard:      expr,
                            names:      symbolset}

  val makeIndexNames : int
                       -> {selectids:  Expression.boundid list,
                           actionsubs: Expression.expr list,
                           guard:      Expression.expr} list
                       -> symbol list
  (* makeIndexNames n ts
   * Return a list of n names for indexing a channel set. The new names will not
   * conflict with any non-selectids used in the guards (i.e. state variables)
   * Prefer names already used within the given list of transitions. *)

  val fromTrans : (symbol * ty) list
                  -> {selectids:  Expression.boundid list,
                      actionsubs: Expression.expr list,
                      guard:      Expression.expr}
                  -> t
  (* fromTrans asubs trans
   * Transform trans into a SelTrans whose channel set is indexed by asubs.
   *
   * The names in asubs must not conflict with non-selectids in guard and
   * actionsubs.
   *
   * First a mapping R is formed from:
   *    -first (needed to handle duplicates) selection bindings used
   *     in index to required bindings
   *        e.g.   R(s) = s_0
   *               R(t) = s_2
   *    -required bindings to fresh names (to avoid capture)
   *        e.g.   R(s_0) = s_0'
   *               R(s_1) = s_1'
   *               R(s_2) = s_2'
   * Then it is used for simultaneous renaming in the selectids and guard.
   *
   * This involves processing each index expression.
   * for a selectid i
   *    -if the type doesn't cover the whole dimension then && in a
   *     restriction clause (l <= s_i <= u) where i has the type int[l,u]
   *    -if used in an earlier index, s_j, then && the clause (s_i == s_j)
   *    -if doesn't match the current name then rename (s_i/i)
   *     and remove i from the list of selectids
   *
   *  for a state expression e:
   *    -throw an exception if it contains selectids
   *    -&& the clause (si == R'(e)) to the guard 
   *)

  val toTrans   : (symbol * ty) list
                  -> t
                  -> {selectids:  Expression.boundid list,
                      actionsubs: Expression.expr list,
                      guard:      Expression.expr}

  (* For the given set of transitions, ensure that all SelectSubs against the
   * same array dimension have the same name. *)

  val toString  : (symbol * ty) list -> t -> string

  val mergeTrans : t list -> t
  (* Merge a list of transitions that have been created for a common channel set
   * indexing list, taking care to avoid selection binding capture. *)

  (* TODO: update *)
  val reduceSelectIds : Environment.env -> t -> t
  (* Assuming: update expressions are ignored
   *
   * Each select binding that:
   *    1) is not used in a SelectSub
   *    2) is not involved in a sub-expression containing clocks
   * is turned into an exists binding.
   *
   * Condition (1) and the assumption mean that the scope of the binding is only
   * important inside the guard expression.
   *
   * Condition (2) ensures that the new guard expression does not split clock
   * zones.
   *
   * Doing this allows maketest to negate transitions that might otherwise fail
   * with a select/forall conflict, such as:
   *    {selectids:  (i : int[0,N - 1])
   *     actionsubs:
   *     guard:      get_status(i)==APPR &&
   *                 (forall (j : int[0,N - 1])
   *                    j!=i && get_status(j)!=AWAY imply status[j][i]<M
   *                 )
   *)
end