% $Id: BoundVarIds.oz,v 1.11 2012/01/17 11:50:53 leavens Exp leavens $ % AUTHOR: Gary T. Leavens \insert 'FreeVarIds.oz' % this includes the set operations. declare % historically we are interested in the bound variables of a statement BoundVarIds = BoundVarIdsStmt fun {BoundVarIdsProgram program(Qs ...)} {UnionList {Map Qs BoundVarIdsQuery}} end fun {BoundVarIdsQuery Q} case Q of seqQuery(S ...) then {BoundVarIdsStmt S} [] declareInQuery(S1 S2 ...) then {Union {Union {BoundVarIdsStmt S1} {BoundVarIdsStmt S2}} {DeclarableVarIdsStmt S1}} % each declarable id is necessarily used [] declareQuery(S ...) then {Union {BoundVarIdsStmt S} {DeclarableVarIdsStmt S}} % each declarable id is necessarily used end end fun {BoundVarIdsStmt Stmt} %% ENSURES: Result is the set of variable identifiers %% that occur bound in Stmt case Stmt of skipStmt then {EmptySet} [] skipStmt(...) then {EmptySet} [] seqStmt(StmtList ...) then {UnionList {Map StmtList BoundVarIds}} [] localStmt(varId(V) Body ...) then {Union {BoundVarIds Body} {Intersect {AsSet [V]} {FreeVarIds Body}}} [] unifyStmt(_ Exp ...) then {BoundVarIdsExp Exp} [] ifStmt(TestExp S1 S2 ...) then {Union {BoundVarIdsExp TestExp} {Union {BoundVarIds S1} {BoundVarIds S2}}} [] caseStmt(Exp Pattern S1 S2 ...) then {Union {BoundVarIdsExp Exp} {Union {Union {BoundVarIds S1} {BoundVarIds S2}} {Intersect {DeclaredIdsPattern Pattern} {FreeVarIds S1}}}} [] applyStmt(ProcExp ArgExpList ...) then {Union {BoundVarIdsExp ProcExp} {UnionList {Map ArgExpList BoundVarIdsExp}}} [] namedFunStmt(_ Formals Body ...) then {Union {BoundVarIdsExp Body} {Intersect {UnionList {Map Formals DeclaredIdsPattern}} {FreeVarIdsExp Body}}} [] inStmt(Pattern Exp Body ...) then {Union {BoundVarIdsExp Exp} {Union {BoundVarIds Body} {Intersect {DeclaredIdsPattern Pattern} {FreeVarIds Body}}}} [] threadStmt(S ...) then {BoundVarIds S} end end fun {BoundVarIdsExp Exp} %% ENSURES: Result is the set of variable identifiers %% that occur bound in Exp case Exp of varId(...) then {EmptySet} [] atomExp(...) then {EmptySet} [] boolExp(...) then {EmptySet} [] intLit(...) then {EmptySet} [] floatLit(...) then {EmptySet} [] recordExp(LabelExp FieldList ...) then {Union {BoundVarIdsExp LabelExp} {UnionList {Map FieldList BoundVarIdsField}}} [] procExp(Formals Body ...) then {Union {BoundVarIds Body} {Intersect {UnionList {Map Formals DeclaredIdsPattern}} {FreeVarIds Body}}} [] ifExp(TestExp E1 E2 ...) then {Union {BoundVarIdsExp TestExp} {Union {BoundVarIdsExp E1} {BoundVarIdsExp E2}}} [] caseExp(Exp Pattern E1 E2 ...) then {Union {BoundVarIdsExp Exp} {Union {Union {BoundVarIdsExp E1} {BoundVarIdsExp E2}} {Intersect {DeclaredIdsPattern Pattern} {FreeVarIdsExp E1}}}} [] applyExp(FunExp ArgExpList ...) then {Union {BoundVarIdsExp FunExp} {UnionList {Map ArgExpList BoundVarIdsExp}}} [] threadExp(E ...) then {BoundVarIdsExp E} end end fun {BoundVarIdsField Field} %% ENSURES: Result is the set of variable identifiers %% that occur bound in Field case Field of colonFld(_ Exp ...) then {BoundVarIdsExp Exp} [] posFld(Exp ...) then {BoundVarIdsExp Exp} end end