//-----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All Rights Reserved.
//
//-----------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------
// BoogiePL - StandardVisitor.cs
//---------------------------------------------------------------------------------------------
using System.Collections.Generic;
using System.Diagnostics.Contracts;
namespace Microsoft.Boogie {
[ContractClass(typeof(VisitorContracts))]
///
/// Base for all classes that process the Absy using the visitor pattern.
///
public abstract class Visitor {
///
/// Switches on node.NodeType to call a visitor method that has been specialized for node.
///
/// The Absy node to be visited.
/// Returns null if node is null. Otherwise returns an updated node (possibly a different object).
public abstract Absy/*!*/ Visit(Absy/*!*/ node);
///
/// Transfers the state from one visitor to another. This enables separate visitor instances to cooperative process a single IR.
///
public virtual void TransferStateTo(Visitor targetVisitor) {
}
public virtual List VisitExprSeq(List list) {
Contract.Requires(list != null);
Contract.Ensures(Contract.Result>() != null);
lock (list)
{
for (int i = 0, n = list.Count; i < n; i++)
list[i] = (Expr)this.Visit(cce.NonNull(list[i]));
}
return list;
}
}
[ContractClassFor(typeof(Visitor))]
abstract class VisitorContracts : Visitor {
public override Absy Visit(Absy node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
throw new System.NotImplementedException();
}
}
///
/// Walks an IR, mutating it into a new form. (For a subclass that does not mutate the IR, see ReadOnlyVisitor.)
///
public abstract class StandardVisitor : Visitor {
public Visitor callingVisitor;
public StandardVisitor() {
}
public StandardVisitor(Visitor callingVisitor) {
this.callingVisitor = callingVisitor;
}
public override Absy Visit(Absy node) {
return node.StdDispatch(this);
}
public virtual Cmd VisitAssertCmd(AssertCmd node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node.Expr = this.VisitExpr(node.Expr);
return node;
}
public virtual Cmd VisitAssignCmd(AssignCmd node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
for (int i = 0; i < node.Lhss.Count; ++i) {
node.Lhss[i] = cce.NonNull((AssignLhs)this.Visit(node.Lhss[i]));
node.Rhss[i] = cce.NonNull((Expr/*!*/)this.Visit(node.Rhss[i]));
}
return node;
}
public virtual Cmd VisitAssumeCmd(AssumeCmd node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node.Expr = this.VisitExpr(node.Expr);
return node;
}
public virtual AtomicRE VisitAtomicRE(AtomicRE node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node.b = this.VisitBlock(node.b);
return node;
}
public virtual Axiom VisitAxiom(Axiom node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node.Expr = this.VisitExpr(node.Expr);
return node;
}
public virtual Type VisitBasicType(BasicType node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
return this.VisitType(node);
}
public virtual BvConcatExpr VisitBvConcatExpr(BvConcatExpr node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node.E0 = this.VisitExpr(node.E0);
node.E1 = this.VisitExpr(node.E1);
return node;
}
public virtual Type VisitBvType(BvType node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
return this.VisitType(node);
}
public virtual Type VisitBvTypeProxy(BvTypeProxy node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
// if the type proxy is instantiated with some more
// specific type, we visit the instantiation
if (node.ProxyFor != null)
return (Type)this.Visit(node.ProxyFor);
return this.VisitType(node);
}
public virtual Block VisitBlock(Block node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node.Cmds = this.VisitCmdSeq(node.Cmds);
node.TransferCmd = (TransferCmd)this.Visit(cce.NonNull(node.TransferCmd));
return node;
}
public virtual Expr VisitCodeExpr(CodeExpr node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node.LocVars = this.VisitVariableSeq(node.LocVars);
node.Blocks = this.VisitBlockList(node.Blocks);
return node;
}
public virtual List VisitBlockSeq(List blockSeq) {
Contract.Requires(blockSeq != null);
Contract.Ensures(Contract.Result>() != null);
lock (blockSeq)
{
for (int i = 0, n = blockSeq.Count; i < n; i++)
blockSeq[i] = this.VisitBlock(cce.NonNull(blockSeq[i]));
}
return blockSeq;
}
public virtual List/*!*/ VisitBlockList(List/*!*/ blocks) {
Contract.Requires(blocks != null);
Contract.Ensures(Contract.Result>() != null);
for (int i = 0, n = blocks.Count; i < n; i++) {
blocks[i] = this.VisitBlock(blocks[i]);
}
return blocks;
}
public virtual BoundVariable VisitBoundVariable(BoundVariable node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node = (BoundVariable)this.VisitVariable(node);
return node;
}
public virtual Cmd VisitCallCmd(CallCmd node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
for (int i = 0; i < node.Ins.Count; ++i)
if (node.Ins[i] != null)
node.Ins[i] = this.VisitExpr(cce.NonNull(node.Ins[i]));
for (int i = 0; i < node.Outs.Count; ++i)
if (node.Outs[i] != null)
node.Outs[i] = (IdentifierExpr)this.VisitIdentifierExpr(cce.NonNull(node.Outs[i]));
return node;
}
public virtual Cmd VisitParCallCmd(ParCallCmd node)
{
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
for (int i = 0; i < node.CallCmds.Count; i++)
{
if (node.CallCmds[i] != null)
node.CallCmds[i] = (CallCmd)this.VisitCallCmd(node.CallCmds[i]);
}
return node;
}
public virtual List VisitCmdSeq(List cmdSeq) {
Contract.Requires(cmdSeq != null);
Contract.Ensures(Contract.Result>() != null);
lock (cmdSeq)
{
for (int i = 0, n = cmdSeq.Count; i < n; i++)
cmdSeq[i] = (Cmd)this.Visit(cce.NonNull(cmdSeq[i])); // call general Visit so subtypes of Cmd get visited by their particular visitor
}
return cmdSeq;
}
public virtual Choice VisitChoice(Choice node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node.rs = this.VisitRESeq(node.rs);
return node;
}
public virtual Cmd VisitCommentCmd(CommentCmd node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
return node;
}
public virtual Constant VisitConstant(Constant node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
return node;
}
public virtual CtorType VisitCtorType(CtorType node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
lock (node)
{
for (int i = 0; i < node.Arguments.Count; ++i)
node.Arguments[i] = cce.NonNull((Type/*!*/)this.Visit(node.Arguments[i]));
}
return node;
}
public virtual Declaration VisitDeclaration(Declaration node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
return node;
}
public virtual List/*!*/ VisitDeclarationList(List/*!*/ declarationList) {
Contract.Requires(declarationList != null);
Contract.Ensures(Contract.Result>() != null);
for (int i = 0, n = declarationList.Count; i < n; i++)
declarationList[i] = cce.NonNull((Declaration/*!*/)this.Visit(declarationList[i]));
return declarationList;
}
public virtual DeclWithFormals VisitDeclWithFormals(DeclWithFormals node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node.InParams = this.VisitVariableSeq(node.InParams);
node.OutParams = this.VisitVariableSeq(node.OutParams);
return node;
}
public virtual ExistsExpr VisitExistsExpr(ExistsExpr node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node = (ExistsExpr)this.VisitQuantifierExpr(node);
return node;
}
public virtual BvExtractExpr VisitBvExtractExpr(BvExtractExpr node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node.Bitvector = this.VisitExpr(node.Bitvector);
return node;
}
public virtual Expr VisitExpr(Expr node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
Expr e = (Expr)this.Visit(node);
return e;
}
public override List VisitExprSeq(List exprSeq) {
//Contract.Requires(exprSeq != null);
Contract.Ensures(Contract.Result>() != null);
for (int i = 0, n = exprSeq.Count; i < n; i++)
exprSeq[i] = this.VisitExpr(cce.NonNull(exprSeq[i]));
return exprSeq;
}
public virtual Requires VisitRequires(Requires @requires) {
Contract.Requires(@requires != null);
Contract.Ensures(Contract.Result() != null);
@requires.Condition = this.VisitExpr(@requires.Condition);
return @requires;
}
public virtual List VisitRequiresSeq(List requiresSeq) {
Contract.Requires(requiresSeq != null);
Contract.Ensures(Contract.Result>() != null);
for (int i = 0, n = requiresSeq.Count; i < n; i++)
requiresSeq[i] = this.VisitRequires(requiresSeq[i]);
return requiresSeq;
}
public virtual Ensures VisitEnsures(Ensures @ensures) {
Contract.Requires(@ensures != null);
Contract.Ensures(Contract.Result() != null);
@ensures.Condition = this.VisitExpr(@ensures.Condition);
return @ensures;
}
public virtual List VisitEnsuresSeq(List ensuresSeq) {
Contract.Requires(ensuresSeq != null);
Contract.Ensures(Contract.Result>() != null);
for (int i = 0, n = ensuresSeq.Count; i < n; i++)
ensuresSeq[i] = this.VisitEnsures(ensuresSeq[i]);
return ensuresSeq;
}
public virtual ForallExpr VisitForallExpr(ForallExpr node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node = (ForallExpr)this.VisitQuantifierExpr(node);
return node;
}
public virtual Expr VisitLambdaExpr(LambdaExpr node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node = (LambdaExpr)this.VisitBinderExpr(node);
return node;
}
public virtual Formal VisitFormal(Formal node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
return node;
}
public virtual Function VisitFunction(Function node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node = (Function)this.VisitDeclWithFormals(node);
if (node.Body != null)
node.Body = this.VisitExpr(node.Body);
return node;
}
public virtual GlobalVariable VisitGlobalVariable(GlobalVariable node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node = (GlobalVariable)this.VisitVariable(node);
return node;
}
public virtual GotoCmd VisitGotoCmd(GotoCmd node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
// do not visit the labelTargets, or control-flow loops will lead to a looping visitor
return node;
}
public virtual Cmd VisitHavocCmd(HavocCmd node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node.Vars = this.VisitIdentifierExprSeq(node.Vars);
return node;
}
public virtual Expr VisitIdentifierExpr(IdentifierExpr node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
if (node.Decl != null)
node.Decl = this.VisitVariable(node.Decl);
return node;
}
public virtual List VisitIdentifierExprSeq(List identifierExprSeq) {
Contract.Requires(identifierExprSeq != null);
Contract.Ensures(Contract.Result>() != null);
lock (identifierExprSeq)
{
for (int i = 0, n = identifierExprSeq.Count; i < n; i++)
identifierExprSeq[i] = (IdentifierExpr)this.VisitIdentifierExpr(cce.NonNull(identifierExprSeq[i]));
}
return identifierExprSeq;
}
public virtual Implementation VisitImplementation(Implementation node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node.LocVars = this.VisitVariableSeq(node.LocVars);
node.Blocks = this.VisitBlockList(node.Blocks);
node.Proc = this.VisitProcedure(cce.NonNull(node.Proc));
node = (Implementation)this.VisitDeclWithFormals(node); // do this first or last?
return node;
}
public virtual LiteralExpr VisitLiteralExpr(LiteralExpr node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
return node;
}
public virtual LocalVariable VisitLocalVariable(LocalVariable node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
return node;
}
public virtual AssignLhs VisitMapAssignLhs(MapAssignLhs node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node.Map = cce.NonNull((AssignLhs)this.Visit(node.Map));
for (int i = 0; i < node.Indexes.Count; ++i)
node.Indexes[i] = cce.NonNull((Expr)this.Visit(node.Indexes[i]));
return node;
}
public virtual MapType VisitMapType(MapType node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
// not doing anything about the bound variables ... maybe
// these should be visited as well ...
//
// NOTE: when overriding this method, you have to make sure that
// the bound variables of the map type are updated correctly
lock (node.Arguments)
{
for (int i = 0; i < node.Arguments.Count; ++i)
node.Arguments[i] = cce.NonNull((Type/*!*/)this.Visit(node.Arguments[i]));
}
node.Result = cce.NonNull((Type/*!*/)this.Visit(node.Result));
return node;
}
public virtual Type VisitMapTypeProxy(MapTypeProxy node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
// if the type proxy is instantiated with some more
// specific type, we visit the instantiation
if (node.ProxyFor != null)
return (Type)this.Visit(node.ProxyFor);
return this.VisitType(node);
}
public virtual Expr VisitNAryExpr(NAryExpr node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node.Args = this.VisitExprSeq(node.Args);
return node;
}
public virtual Expr VisitOldExpr(OldExpr node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node.Expr = this.VisitExpr(node.Expr);
return node;
}
public virtual Procedure VisitProcedure(Procedure node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node.Ensures = this.VisitEnsuresSeq(node.Ensures);
node.InParams = this.VisitVariableSeq(node.InParams);
node.Modifies = this.VisitIdentifierExprSeq(node.Modifies);
node.OutParams = this.VisitVariableSeq(node.OutParams);
node.Requires = this.VisitRequiresSeq(node.Requires);
return node;
}
public virtual Program VisitProgram(Program node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node.TopLevelDeclarations = this.VisitDeclarationList(node.TopLevelDeclarations);
return node;
}
public virtual QKeyValue VisitQKeyValue(QKeyValue node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
for (int i = 0, n = node.Params.Count; i < n; i++) {
var e = node.Params[i] as Expr;
if (e != null) {
node.Params[i] = (Expr)this.Visit(e);
}
}
if (node.Next != null) {
node.Next = (QKeyValue)this.Visit(node.Next);
}
return node;
}
public virtual BinderExpr VisitBinderExpr(BinderExpr node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node.Body = this.VisitExpr(node.Body);
node.Dummies = this.VisitVariableSeq(node.Dummies);
//node.Type = this.VisitType(node.Type);
return node;
}
public virtual QuantifierExpr VisitQuantifierExpr(QuantifierExpr node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node = cce.NonNull((QuantifierExpr)this.VisitBinderExpr(node));
if (node.Triggers != null) {
node.Triggers = this.VisitTrigger(node.Triggers);
}
return node;
}
public virtual Cmd VisitRE(RE node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
return (Cmd)this.Visit(node); // Call general visit so subtypes get visited by their particular visitor
}
public virtual List VisitRESeq(List reSeq) {
Contract.Requires(reSeq != null);
Contract.Ensures(Contract.Result>() != null);
for (int i = 0, n = reSeq.Count; i < n; i++)
reSeq[i] = (RE)this.VisitRE(cce.NonNull(reSeq[i]));
return reSeq;
}
public virtual ReturnCmd VisitReturnCmd(ReturnCmd node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
return (ReturnCmd)this.VisitTransferCmd(node);
}
public virtual ReturnExprCmd VisitReturnExprCmd(ReturnExprCmd node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node.Expr = this.VisitExpr(node.Expr);
return node;
}
public virtual Sequential VisitSequential(Sequential node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node.first = (RE)this.VisitRE(node.first);
node.second = (RE)this.VisitRE(node.second);
return node;
}
public virtual AssignLhs VisitSimpleAssignLhs(SimpleAssignLhs node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node.AssignedVariable =
(IdentifierExpr)this.VisitIdentifierExpr(node.AssignedVariable);
return node;
}
public virtual Cmd VisitStateCmd(StateCmd node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node.Locals = this.VisitVariableSeq(node.Locals);
node.Cmds = this.VisitCmdSeq(node.Cmds);
return node;
}
public virtual TransferCmd VisitTransferCmd(TransferCmd node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
return node;
}
public virtual Trigger VisitTrigger(Trigger node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
Trigger origNext = node.Next;
if (origNext != null) {
Trigger newNext = this.VisitTrigger(origNext);
if (newNext != origNext) {
node = new Trigger(node.tok, node.Pos, node.Tr); // note: this creates sharing between the old and new Tr sequence
node.Next = newNext;
}
}
node.Tr = this.VisitExprSeq(node.Tr);
return node;
}
// called by default for all nullary type constructors and type variables
public virtual Type VisitType(Type node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
return node;
}
public virtual TypedIdent VisitTypedIdent(TypedIdent node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node.Type = (Type)this.Visit(node.Type);
return node;
}
public virtual Declaration VisitTypeCtorDecl(TypeCtorDecl node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
return this.VisitDeclaration(node);
}
public virtual Type VisitTypeSynonymAnnotation(TypeSynonymAnnotation node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node.ExpandedType = cce.NonNull((Type/*!*/)this.Visit(node.ExpandedType));
lock (node.Arguments)
{
for (int i = 0; i < node.Arguments.Count; ++i)
node.Arguments[i] = cce.NonNull((Type/*!*/)this.Visit(node.Arguments[i]));
}
return node;
}
public virtual Declaration VisitTypeSynonymDecl(TypeSynonymDecl node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
return this.VisitDeclaration(node);
}
public virtual Type VisitTypeVariable(TypeVariable node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
return this.VisitType(node);
}
public virtual Type VisitTypeProxy(TypeProxy node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
// if the type proxy is instantiated with some more
// specific type, we visit the instantiation
if (node.ProxyFor != null)
return cce.NonNull((Type/*!*/)this.Visit(node.ProxyFor));
return this.VisitType(node);
}
public virtual Type VisitUnresolvedTypeIdentifier(UnresolvedTypeIdentifier node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
return this.VisitType(node);
}
public virtual Variable VisitVariable(Variable node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node.TypedIdent = this.VisitTypedIdent(node.TypedIdent);
return node;
}
public virtual List VisitVariableSeq(List variableSeq) {
Contract.Requires(variableSeq != null);
Contract.Ensures(Contract.Result>() != null);
lock (variableSeq)
{
for (int i = 0, n = variableSeq.Count; i < n; i++)
variableSeq[i] = this.VisitVariable(cce.NonNull(variableSeq[i]));
}
return variableSeq;
}
public virtual YieldCmd VisitYieldCmd(YieldCmd node)
{
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
return node;
}
public virtual Cmd VisitAssertEnsuresCmd(AssertEnsuresCmd node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node.Ensures = this.VisitEnsures(node.Ensures);
node.Expr = this.VisitExpr(node.Expr);
return node;
}
public virtual Cmd VisitAssertRequiresCmd(AssertRequiresCmd node) {
Contract.Requires(node != null);
Contract.Ensures(Contract.Result() != null);
node.Requires = this.VisitRequires(node.Requires);
node.Expr = this.VisitExpr(node.Expr);
return node;
}
}
///
/// A ReadOnlyVisitor visits all the nodes of a given Absy. The visitor may collect information from
/// the nodes, may change fields contained in the data structure, but may not replace any nodes in the
/// data structure. To enforce this, all Visit...(node) methods have a postcondition that says that
/// the return value is equal to the given "node".
///
public abstract class ReadOnlyVisitor : StandardVisitor
{
public ReadOnlyVisitor()
{
}
public ReadOnlyVisitor(Visitor callingVisitor)
{
this.callingVisitor = callingVisitor;
}
public override Absy Visit(Absy node)
{
Contract.Ensures(Contract.Result() == node);
return node.StdDispatch(this);
}
public override Cmd VisitAssertCmd(AssertCmd node)
{
Contract.Ensures(Contract.Result() == node);
this.VisitExpr(node.Expr);
return node;
}
public override Cmd VisitAssignCmd(AssignCmd node)
{
Contract.Ensures(Contract.Result() == node);
for (int i = 0; i < node.Lhss.Count; ++i)
{
this.Visit(node.Lhss[i]);
this.Visit(node.Rhss[i]);
}
return node;
}
public override Cmd VisitAssumeCmd(AssumeCmd node)
{
Contract.Ensures(Contract.Result() == node);
this.VisitExpr(node.Expr);
return node;
}
public override AtomicRE VisitAtomicRE(AtomicRE node)
{
Contract.Ensures(Contract.Result() == node);
this.VisitBlock(node.b);
return node;
}
public override Axiom VisitAxiom(Axiom node)
{
Contract.Ensures(Contract.Result() == node);
this.VisitExpr(node.Expr);
return node;
}
public override Type VisitBasicType(BasicType node)
{
Contract.Ensures(Contract.Result() == node);
return this.VisitType(node);
}
public override BvConcatExpr VisitBvConcatExpr(BvConcatExpr node)
{
Contract.Ensures(Contract.Result() == node);
this.VisitExpr(node.E0);
this.VisitExpr(node.E1);
return node;
}
public override Type VisitBvType(BvType node)
{
Contract.Ensures(Contract.Result() == node);
return this.VisitType(node);
}
public override Type VisitBvTypeProxy(BvTypeProxy node)
{
Contract.Ensures(Contract.Result() == node);
// if the type proxy is instantiated with some more
// specific type, we visit the instantiation
if (node.ProxyFor != null)
this.Visit(node.ProxyFor);
return this.VisitType(node);
}
public override Block VisitBlock(Block node)
{
Contract.Ensures(Contract.Result() == node);
this.VisitCmdSeq(node.Cmds);
this.Visit(cce.NonNull(node.TransferCmd));
return node;
}
public override Expr VisitCodeExpr(CodeExpr node)
{
Contract.Ensures(Contract.Result() == node);
this.VisitVariableSeq(node.LocVars);
this.VisitBlockList(node.Blocks);
return node;
}
public override List VisitBlockSeq(List blockSeq)
{
Contract.Ensures(Contract.Result>() == blockSeq);
for (int i = 0, n = blockSeq.Count; i < n; i++)
this.VisitBlock(cce.NonNull(blockSeq[i]));
return blockSeq;
}
public override List/*!*/ VisitBlockList(List/*!*/ blocks)
{
Contract.Ensures(Contract.Result>() == blocks);
for (int i = 0, n = blocks.Count; i < n; i++)
{
this.VisitBlock(blocks[i]);
}
return blocks;
}
public override BoundVariable VisitBoundVariable(BoundVariable node)
{
Contract.Ensures(Contract.Result() == node);
return (BoundVariable)this.VisitVariable(node);
}
public override Cmd VisitCallCmd(CallCmd node)
{
Contract.Ensures(Contract.Result() == node);
for (int i = 0; i < node.Ins.Count; ++i)
if (node.Ins[i] != null)
this.VisitExpr(node.Ins[i]);
for (int i = 0; i < node.Outs.Count; ++i)
if (node.Outs[i] != null)
this.VisitIdentifierExpr(node.Outs[i]);
return node;
}
public override Cmd VisitParCallCmd(ParCallCmd node)
{
Contract.Ensures(Contract.Result() == node);
for (int i = 0; i < node.CallCmds.Count; i++)
{
if (node.CallCmds[i] != null)
this.VisitCallCmd(node.CallCmds[i]);
}
return node;
}
public override List VisitCmdSeq(List cmdSeq)
{
Contract.Ensures(Contract.Result>() == cmdSeq);
for (int i = 0, n = cmdSeq.Count; i < n; i++)
this.Visit(cce.NonNull(cmdSeq[i])); // call general Visit so subtypes of Cmd get visited by their particular visitor
return cmdSeq;
}
public override Choice VisitChoice(Choice node)
{
Contract.Ensures(Contract.Result() == node);
this.VisitRESeq(node.rs);
return node;
}
public override Cmd VisitCommentCmd(CommentCmd node)
{
Contract.Ensures(Contract.Result() == node);
return node;
}
public override Constant VisitConstant(Constant node)
{
Contract.Ensures(Contract.Result() == node);
return node;
}
public override CtorType VisitCtorType(CtorType node)
{
Contract.Ensures(Contract.Result() == node);
for (int i = 0; i < node.Arguments.Count; ++i)
this.Visit(node.Arguments[i]);
return node;
}
public override Declaration VisitDeclaration(Declaration node)
{
Contract.Ensures(Contract.Result() == node);
return node;
}
public override List/*!*/ VisitDeclarationList(List/*!*/ declarationList)
{
Contract.Ensures(Contract.Result>() == declarationList);
for (int i = 0, n = declarationList.Count; i < n; i++)
this.Visit(declarationList[i]);
return declarationList;
}
public override DeclWithFormals VisitDeclWithFormals(DeclWithFormals node)
{
Contract.Ensures(Contract.Result() == node);
this.VisitVariableSeq(node.InParams);
this.VisitVariableSeq(node.OutParams);
return node;
}
public override ExistsExpr VisitExistsExpr(ExistsExpr node)
{
Contract.Ensures(Contract.Result() == node);
return (ExistsExpr)this.VisitQuantifierExpr(node);
}
public override BvExtractExpr VisitBvExtractExpr(BvExtractExpr node)
{
Contract.Ensures(Contract.Result() == node);
this.VisitExpr(node.Bitvector);
return node;
}
public override Expr VisitExpr(Expr node)
{
Contract.Ensures(Contract.Result() == node);
return (Expr)this.Visit(node);
}
public override List VisitExprSeq(List exprSeq)
{
Contract.Ensures(Contract.Result>() == exprSeq);
for (int i = 0, n = exprSeq.Count; i < n; i++)
this.VisitExpr(cce.NonNull(exprSeq[i]));
return exprSeq;
}
public override Requires VisitRequires(Requires requires)
{
Contract.Ensures(Contract.Result() == requires);
this.VisitExpr(requires.Condition);
return requires;
}
public override List VisitRequiresSeq(List requiresSeq)
{
Contract.Ensures(Contract.Result>() == requiresSeq);
for (int i = 0, n = requiresSeq.Count; i < n; i++)
this.VisitRequires(requiresSeq[i]);
return requiresSeq;
}
public override Ensures VisitEnsures(Ensures ensures)
{
Contract.Ensures(Contract.Result() == ensures);
this.VisitExpr(ensures.Condition);
return ensures;
}
public override List VisitEnsuresSeq(List ensuresSeq)
{
Contract.Ensures(Contract.Result>() == ensuresSeq);
for (int i = 0, n = ensuresSeq.Count; i < n; i++)
this.VisitEnsures(ensuresSeq[i]);
return ensuresSeq;
}
public override ForallExpr VisitForallExpr(ForallExpr node)
{
Contract.Ensures(Contract.Result() == node);
return (ForallExpr)this.VisitQuantifierExpr(node);
}
public override Expr VisitLambdaExpr(LambdaExpr node) {
Contract.Ensures(Contract.Result() == node);
return this.VisitBinderExpr(node);
}
public override Formal VisitFormal(Formal node)
{
Contract.Ensures(Contract.Result() == node);
return node;
}
public override Function VisitFunction(Function node)
{
Contract.Ensures(Contract.Result() == node);
node = (Function)this.VisitDeclWithFormals(node);
if (node.Body != null)
this.VisitExpr(node.Body);
return node;
}
public override GlobalVariable VisitGlobalVariable(GlobalVariable node)
{
Contract.Ensures(Contract.Result() == node);
return (GlobalVariable)this.VisitVariable(node);
}
public override GotoCmd VisitGotoCmd(GotoCmd node)
{
Contract.Ensures(Contract.Result() == node);
// do not visit the labelTargets, or control-flow loops will lead to a looping visitor
return node;
}
public override Cmd VisitHavocCmd(HavocCmd node)
{
Contract.Ensures(Contract.Result() == node);
this.VisitIdentifierExprSeq(node.Vars);
return node;
}
public override Expr VisitIdentifierExpr(IdentifierExpr node)
{
Contract.Ensures(Contract.Result() == node);
if (node.Decl != null)
this.VisitVariable(node.Decl);
return node;
}
public override List VisitIdentifierExprSeq(List identifierExprSeq)
{
Contract.Ensures(Contract.Result>() == identifierExprSeq);
for (int i = 0, n = identifierExprSeq.Count; i < n; i++)
this.VisitIdentifierExpr(cce.NonNull(identifierExprSeq[i]));
return identifierExprSeq;
}
public override Implementation VisitImplementation(Implementation node)
{
Contract.Ensures(Contract.Result() == node);
this.VisitVariableSeq(node.LocVars);
this.VisitBlockList(node.Blocks);
this.VisitProcedure(cce.NonNull(node.Proc));
return (Implementation)this.VisitDeclWithFormals(node); // do this first or last?
}
public override LiteralExpr VisitLiteralExpr(LiteralExpr node)
{
Contract.Ensures(Contract.Result() == node);
return node;
}
public override LocalVariable VisitLocalVariable(LocalVariable node)
{
Contract.Ensures(Contract.Result() == node);
return node;
}
public override AssignLhs VisitMapAssignLhs(MapAssignLhs node)
{
Contract.Ensures(Contract.Result() == node);
this.Visit(node.Map);
for (int i = 0; i < node.Indexes.Count; ++i)
this.Visit(node.Indexes[i]);
return node;
}
public override MapType VisitMapType(MapType node)
{
Contract.Ensures(Contract.Result() == node);
// not doing anything about the bound variables ... maybe
// these should be visited as well ...
//
// NOTE: when overriding this method, you have to make sure that
// the bound variables of the map type are updated correctly
for (int i = 0; i < node.Arguments.Count; ++i)
this.Visit(node.Arguments[i]);
this.Visit(node.Result);
return node;
}
public override Type VisitMapTypeProxy(MapTypeProxy node)
{
Contract.Ensures(Contract.Result() == node);
// if the type proxy is instantiated with some more
// specific type, we visit the instantiation
if (node.ProxyFor != null)
this.Visit(node.ProxyFor);
return this.VisitType(node);
}
public override Expr VisitNAryExpr(NAryExpr node)
{
Contract.Ensures(Contract.Result() == node);
this.VisitExprSeq(node.Args);
return node;
}
public override Expr VisitOldExpr(OldExpr node)
{
Contract.Ensures(Contract.Result() == node);
this.VisitExpr(node.Expr);
return node;
}
public override Procedure VisitProcedure(Procedure node)
{
Contract.Ensures(Contract.Result() == node);
this.VisitEnsuresSeq(node.Ensures);
this.VisitVariableSeq(node.InParams);
this.VisitIdentifierExprSeq(node.Modifies);
this.VisitVariableSeq(node.OutParams);
this.VisitRequiresSeq(node.Requires);
return node;
}
public override Program VisitProgram(Program node)
{
Contract.Ensures(Contract.Result() == node);
this.VisitDeclarationList(node.TopLevelDeclarations);
return node;
}
public override QKeyValue VisitQKeyValue(QKeyValue node) {
Contract.Ensures(Contract.Result() == node);
for (int i = 0, n = node.Params.Count; i < n; i++) {
var e = node.Params[i] as Expr;
if (e != null) {
this.Visit(e);
}
}
if (node.Next != null) {
this.Visit(node.Next);
}
return node;
}
public override BinderExpr VisitBinderExpr(BinderExpr node)
{
Contract.Ensures(Contract.Result() == node);
this.VisitExpr(node.Body);
this.VisitVariableSeq(node.Dummies);
// this.VisitType(node.Type);
return node;
}
public override QuantifierExpr VisitQuantifierExpr(QuantifierExpr node)
{
Contract.Ensures(Contract.Result() == node);
this.VisitBinderExpr(node);
if (node.Triggers != null)
{
this.VisitTrigger(node.Triggers);
}
return node;
}
public override Cmd VisitRE(RE node)
{
Contract.Ensures(Contract.Result() == node);
return (Cmd)this.Visit(node); // Call general visit so subtypes get visited by their particular visitor
}
public override List VisitRESeq(List reSeq)
{
Contract.Ensures(Contract.Result>() == reSeq);
for (int i = 0, n = reSeq.Count; i < n; i++)
this.VisitRE(cce.NonNull(reSeq[i]));
return reSeq;
}
public override ReturnCmd VisitReturnCmd(ReturnCmd node)
{
Contract.Ensures(Contract.Result() == node);
return (ReturnCmd)this.VisitTransferCmd(node);
}
public override ReturnExprCmd VisitReturnExprCmd(ReturnExprCmd node)
{
Contract.Ensures(Contract.Result() == node);
this.VisitExpr(node.Expr);
return node;
}
public override Sequential VisitSequential(Sequential node)
{
Contract.Ensures(Contract.Result() == node);
this.VisitRE(node.first);
this.VisitRE(node.second);
return node;
}
public override AssignLhs VisitSimpleAssignLhs(SimpleAssignLhs node)
{
Contract.Ensures(Contract.Result() == node);
this.VisitIdentifierExpr(node.AssignedVariable);
return node;
}
public override Cmd VisitStateCmd(StateCmd node)
{
Contract.Ensures(Contract.Result() == node);
this.VisitVariableSeq(node.Locals);
this.VisitCmdSeq(node.Cmds);
return node;
}
public override TransferCmd VisitTransferCmd(TransferCmd node)
{
Contract.Ensures(Contract.Result() == node);
return node;
}
public override Trigger VisitTrigger(Trigger node)
{
Contract.Ensures(Contract.Result() == node);
Trigger origNext = node.Next;
if (origNext != null)
{
this.VisitTrigger(origNext);
}
this.VisitExprSeq(node.Tr);
return node;
}
// called by default for all nullary type constructors and type variables
public override Type VisitType(Type node)
{
Contract.Ensures(Contract.Result() == node);
return node;
}
public override TypedIdent VisitTypedIdent(TypedIdent node)
{
Contract.Ensures(Contract.Result() == node);
this.Visit(node.Type);
return node;
}
public override Declaration VisitTypeCtorDecl(TypeCtorDecl node)
{
Contract.Ensures(Contract.Result() == node);
return this.VisitDeclaration(node);
}
public override Type VisitTypeSynonymAnnotation(TypeSynonymAnnotation node)
{
Contract.Ensures(Contract.Result() == node);
node.ExpandedType = cce.NonNull((Type/*!*/)this.Visit(node.ExpandedType));
for (int i = 0; i < node.Arguments.Count; ++i)
this.Visit(node.Arguments[i]);
return node;
}
public override Declaration VisitTypeSynonymDecl(TypeSynonymDecl node)
{
Contract.Ensures(Contract.Result() == node);
return this.VisitDeclaration(node);
}
public override Type VisitTypeVariable(TypeVariable node)
{
Contract.Ensures(Contract.Result() == node);
return this.VisitType(node);
}
public override Type VisitTypeProxy(TypeProxy node)
{
Contract.Ensures(Contract.Result() == node);
// if the type proxy is instantiated with some more
// specific type, we visit the instantiation
if (node.ProxyFor != null)
this.Visit(node.ProxyFor);
return this.VisitType(node);
}
public override Type VisitUnresolvedTypeIdentifier(UnresolvedTypeIdentifier node)
{
Contract.Ensures(Contract.Result() == node);
return this.VisitType(node);
}
public override Variable VisitVariable(Variable node)
{
Contract.Ensures(Contract.Result() == node);
this.VisitTypedIdent(node.TypedIdent);
return node;
}
public override List VisitVariableSeq(List variableSeq)
{
Contract.Ensures(Contract.Result>() == variableSeq);
for (int i = 0, n = variableSeq.Count; i < n; i++)
this.VisitVariable(cce.NonNull(variableSeq[i]));
return variableSeq;
}
public override YieldCmd VisitYieldCmd(YieldCmd node)
{
Contract.Ensures(Contract.Result() == node);
return node;
}
public override Cmd VisitAssertEnsuresCmd(AssertEnsuresCmd node)
{
Contract.Ensures(Contract.Result() == node);
this.VisitEnsures(node.Ensures);
this.VisitExpr(node.Expr);
return node;
}
public override Cmd VisitAssertRequiresCmd(AssertRequiresCmd node)
{
Contract.Ensures(Contract.Result() == node);
this.VisitRequires(node.Requires);
this.VisitExpr(node.Expr);
return node;
}
}
}