module rename-test
imports libstratego-lib
strategies

  main = 
    test-suite(!"rename-test",
	test1;
	test2
    )

// First example: untyped lambda calculus
signature
  sorts Exp
  constructors
    Abs : String * Exp -> Exp
    Var : String -> Exp
    App : Exp * Exp -> Exp
rules

  EBnd : Abs(x, e) -> [x]

strategies

  is-evar(s) = Var(s)

  EPaste(nwvars) =
    Abs(nwvars; Hd, id)

  EBoundIn(bndvars, ubndvars,ignore) =
    Abs(ignore, bndvars)

  erename = 
    rename(is-evar, EBnd, EBoundIn, EPaste)

strategies

   test1 = 
     apply-and-check(!"test1"
	, erename
	, !App(Abs("x", Var("x")), Var("x"))
	, {?App(Abs(a_0,Var(a_0)),Var("x")); where(<not(eq)> (a_0, "x"))}
	)


// Second example: typed lambda calculus
signature
  sorts Exp
  constructors
    Abs    : String * Type * Exp -> Exp
    Var    : String * Type -> Exp
    Letrec : List(Fdec) * Exp -> Exp
    Fdec   : String * Type * Exp -> Fdec
rules

  TBnd : Abs(x, t, e) -> [x]
  TBnd : Letrec(fdecs, e) -> <map(Name)> fdecs

  Name : Fdec(f, t, e) -> f

strategies

  is-var(s) = Var(debug; s; debug, id)

  TBoundIn(bndvars, ubndvars, ignore) =
    Abs(ignore, ignore, bndvars) +
    Letrec(bndvars, bndvars)

  TPaste(nwvars) = debug; (
    Abs(nwvars; Hd, id, id) +
    Letrec(split(id,nwvars); zip(PasteFdec), id)
  ); debug

  PasteFdec : 
    (Fdec(f, t, e), g) -> Fdec(g, t, e)

  trename = 
    rename(is-var, TBnd, TBoundIn, TPaste)


//  Tests
strategies

   test2 = 
     apply-and-check(!"test2"
	, trename
	, !App(Abs("x",   "a", Var("x",   "a")), Var("x", "a"))
	, {?App(Abs(b_0, "a", Var(b_0, "a")), Var("x", "a")); where(<not(eq)> (b_0, "a"))}
	)
