public override Expr VisitCodeExpr(CodeExpr node) { //Contract.Requires(node != null); Contract.Ensures(Contract.Result <Expr>() != null); CodeExpr clone = (CodeExpr)base.VisitCodeExpr((CodeExpr)node.Clone()); // Before returning, fix up the resolved goto targets Contract.Assert(node.Blocks.Count == clone.Blocks.Count); Dictionary <Block, Block> subst = new Dictionary <Block, Block>(); for (int i = 0; i < node.Blocks.Count; i++) { subst.Add(node.Blocks[i], clone.Blocks[i]); } foreach (Block /*!*/ b in clone.Blocks) { Contract.Assert(b != null); GotoCmd g = b.TransferCmd as GotoCmd; if (g != null) { List <Block> targets = new List <Block>(); foreach (Block t in cce.NonNull(g.labelTargets)) { Block nt = subst[t]; targets.Add(nt); } g.labelTargets = targets; } } return(clone); }
public override Expr VisitCodeExpr(CodeExpr node) { var clone = (CodeExpr)node.Clone(); clone.Blocks = new List <Block>(node.Blocks); clone.LocVars = new List <Variable>(node.LocVars); clone = (CodeExpr)base.VisitCodeExpr(clone); // Before returning, fix up the resolved goto targets Dictionary <Block, Block> subst = new Dictionary <Block, Block>(); for (int i = 0; i < node.Blocks.Count; i++) { subst.Add(node.Blocks[i], clone.Blocks[i]); } foreach (Block b in clone.Blocks) { GotoCmd g = b.TransferCmd as GotoCmd; if (g != null) { List <Block> targets = new List <Block>(); foreach (Block t in g.labelTargets) { Block nt = subst[t]; targets.Add(nt); } g.labelTargets = targets; } } return(clone); }
public override Expr VisitCodeExpr(CodeExpr node) { Inliner codeExprInliner = new Inliner(program, inlineCallback, CommandLineOptions.Clo.InlineDepth); codeExprInliner.newLocalVars.AddRange(node.LocVars); codeExprInliner.inlinedProcLblMap = this.inlinedProcLblMap; List<Block> newCodeExprBlocks = codeExprInliner.DoInlineBlocks(node.Blocks, ref inlinedSomething); return new CodeExpr(codeExprInliner.newLocalVars, newCodeExprBlocks); }
public virtual Expr VisitCodeExpr(CodeExpr node) { Contract.Requires(node != null); Contract.Ensures(Contract.Result <Expr>() != null); node.LocVars = this.VisitVariableSeq(node.LocVars); node.Blocks = this.VisitBlockList(node.Blocks); return(node); }
public ModelViewInfo(CodeExpr codeExpr) { Contract.Requires(codeExpr != null); // TODO: also need all variables of enclosing scopes (the global variables of the program, the parameters // and perhaps locals of the implementation (if any), any enclosing code expressions). foreach (Variable v in codeExpr.LocVars) { AllVariables.Add(v); } }
public override Expr VisitCodeExpr(CodeExpr node) { //Contract.Requires(node != null); Contract.Ensures(Contract.Result<Expr>() != null); CodeExpr clone = (CodeExpr)base.VisitCodeExpr((CodeExpr)node.Clone()); // Before returning, fix up the resolved goto targets Contract.Assert(node.Blocks.Count == clone.Blocks.Count); Dictionary<Block, Block> subst = new Dictionary<Block, Block>(); for (int i = 0; i < node.Blocks.Count; i++) { subst.Add(node.Blocks[i], clone.Blocks[i]); } foreach (Block/*!*/ b in clone.Blocks) { Contract.Assert(b != null); GotoCmd g = b.TransferCmd as GotoCmd; if (g != null) { List<Block> targets = new List<Block>(); foreach (Block t in cce.NonNull(g.labelTargets)) { Block nt = subst[t]; targets.Add(nt); } g.labelTargets = targets; } } return clone; }
public void TypeCheck() { foreach (Declaration decl in program.TopLevelDeclarations) { Procedure proc = decl as Procedure; if (proc == null) { continue; } foreach (Ensures e in proc.Ensures) { int phaseNum; MoverType moverType = MoverCheck.GetMoverType(e, out phaseNum); if (moverType == MoverType.Top) { continue; } CodeExpr codeExpr = e.Condition as CodeExpr; if (codeExpr == null) { Error(e, "An atomic action must be a CodeExpr"); continue; } if (procToActionInfo.ContainsKey(proc)) { Error(proc, "A procedure can have at most one atomic action"); continue; } procToActionInfo[proc] = new ActionInfo(proc, codeExpr, moverType, phaseNum); } } this.VisitProgram(program); #if QED YieldTypeChecker.PerformYieldTypeChecking(this); #endif }
public virtual Expr VisitCodeExpr(CodeExpr node) { Contract.Requires(node != null); Contract.Ensures(Contract.Result<Expr>() != null); node.LocVars = this.VisitVariableSeq(node.LocVars); node.Blocks = this.VisitBlockList(node.Blocks); return node; }
public AtomicActionInfo(Procedure proc, Ensures ensures, MoverType moverType, int layerNum, int availableUptoLayerNum) : base(proc, layerNum, availableUptoLayerNum) { this.ensures = ensures; this.moverType = moverType; this.gate = new List<AssertCmd>(); this.action = ensures.Condition as CodeExpr; this.thisGate = new List<AssertCmd>(); this.thisInParams = new List<Variable>(); this.thisOutParams = new List<Variable>(); this.thatGate = new List<AssertCmd>(); this.thatInParams = new List<Variable>(); this.thatOutParams = new List<Variable>(); this.hasAssumeCmd = false; this.thisMap = new Dictionary<Variable, Expr>(); this.thatMap = new Dictionary<Variable, Expr>(); this.triggerFuns = new Dictionary<Variable, Function>(); foreach (Block block in this.action.Blocks) { block.Cmds.ForEach(x => this.hasAssumeCmd = this.hasAssumeCmd || x is AssumeCmd); } foreach (Block block in this.action.Blocks) { if (block.TransferCmd is ReturnExprCmd) { block.TransferCmd = new ReturnCmd(block.TransferCmd.tok); } } var cmds = this.action.Blocks[0].Cmds; for (int i = 0; i < cmds.Count; i++) { AssertCmd assertCmd = cmds[i] as AssertCmd; if (assertCmd == null) break; this.gate.Add(assertCmd); cmds[i] = new AssumeCmd(assertCmd.tok, Expr.True); } foreach (Variable x in proc.InParams) { Variable thisx = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "this_" + x.Name, x.TypedIdent.Type), true, x.Attributes); this.thisInParams.Add(thisx); this.thisMap[x] = Expr.Ident(thisx); Variable thatx = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), true, x.Attributes); this.thatInParams.Add(thatx); this.thatMap[x] = Expr.Ident(thatx); } foreach (Variable x in proc.OutParams) { Variable thisx = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "this_" + x.Name, x.TypedIdent.Type), false, x.Attributes); this.thisOutParams.Add(thisx); this.thisMap[x] = Expr.Ident(thisx); Variable thatx = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), false, x.Attributes); this.thatOutParams.Add(thatx); this.thatMap[x] = Expr.Ident(thatx); } List<Variable> thisLocVars = new List<Variable>(); List<Variable> thatLocVars = new List<Variable>(); foreach (Variable x in this.action.LocVars) { Variable thisx = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "this_" + x.Name, x.TypedIdent.Type), false); thisMap[x] = Expr.Ident(thisx); thisLocVars.Add(thisx); Variable thatx = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), false); thatMap[x] = Expr.Ident(thatx); thatLocVars.Add(thatx); } Contract.Assume(proc.TypeParameters.Count == 0); Substitution thisSubst = Substituter.SubstitutionFromHashtable(this.thisMap); Substitution thatSubst = Substituter.SubstitutionFromHashtable(this.thatMap); foreach (AssertCmd assertCmd in this.gate) { this.thisGate.Add((AssertCmd)Substituter.Apply(thisSubst, assertCmd)); this.thatGate.Add((AssertCmd)Substituter.Apply(thatSubst, assertCmd)); } this.thisAction = new CodeExpr(thisLocVars, SubstituteBlocks(this.action.Blocks, thisSubst, "this_")); this.thatAction = new CodeExpr(thatLocVars, SubstituteBlocks(this.action.Blocks, thatSubst, "that_")); { VariableCollector collector = new VariableCollector(); collector.Visit(this.action); this.actionUsedGlobalVars = new HashSet<Variable>(collector.usedVars.Where(x => x is GlobalVariable)); } List<Variable> modifiedVars = new List<Variable>(); foreach (Block block in this.action.Blocks) { block.Cmds.ForEach(cmd => cmd.AddAssignedVariables(modifiedVars)); } this.modifiedGlobalVars = new HashSet<Variable>(modifiedVars.Where(x => x is GlobalVariable)); { VariableCollector collector = new VariableCollector(); this.gate.ForEach(assertCmd => collector.Visit(assertCmd)); this.gateUsedGlobalVars = new HashSet<Variable>(collector.usedVars.Where(x => x is GlobalVariable)); } }
void AtomExpression(out Expr/*!*/ e) { Contract.Ensures(Contract.ValueAtReturn(out e) != null); IToken/*!*/ x; int n; BigNum bn; BigDec bd; BigFloat bf; List<Expr>/*!*/ es; List<Variable>/*!*/ ds; Trigger trig; List<TypeVariable>/*!*/ typeParams; IdentifierExpr/*!*/ id; QKeyValue kv; e = dummyExpr; List<Variable>/*!*/ locals; List<Block/*!*/>/*!*/ blocks; switch (la.kind) { case 83: { Get(); e = new LiteralExpr(t, false); break; } case 84: { Get(); e = new LiteralExpr(t, true); break; } case 3: { Nat(out bn); e = new LiteralExpr(t, bn); break; } case 5: case 6: { Dec(out bd); e = new LiteralExpr(t, bd); break; } case 7: { Float(out bf); e = new LiteralExpr(t, bf); break; } case 2: { BvLit(out bn, out n); e = new LiteralExpr(t, bn, n); break; } case 1: { Ident(out x); id = new IdentifierExpr(x, x.val); e = id; if (la.kind == 10) { Get(); if (StartOf(9)) { Expressions(out es); e = new NAryExpr(x, new FunctionCall(id), es); } else if (la.kind == 11) { e = new NAryExpr(x, new FunctionCall(id), new List<Expr>()); } else SynErr(124); Expect(11); } break; } case 85: { Get(); x = t; Expect(10); Expression(out e); Expect(11); e = new OldExpr(x, e); break; } case 15: { Get(); x = t; Expect(10); Expression(out e); Expect(11); e = new NAryExpr(x, new ArithmeticCoercion(x, ArithmeticCoercion.CoercionType.ToInt), new List<Expr>{ e }); break; } case 16: { Get(); x = t; Expect(10); Expression(out e); Expect(11); e = new NAryExpr(x, new ArithmeticCoercion(x, ArithmeticCoercion.CoercionType.ToReal), new List<Expr>{ e }); break; } case 10: { Get(); if (StartOf(9)) { Expression(out e); if (e is BvBounds) this.SemErr("parentheses around bitvector bounds " + "are not allowed"); } else if (la.kind == 89 || la.kind == 90) { Forall(); x = t; QuantifierBody(x, out typeParams, out ds, out kv, out trig, out e); if (typeParams.Count + ds.Count > 0) e = new ForallExpr(x, typeParams, ds, kv, trig, e); } else if (la.kind == 91 || la.kind == 92) { Exists(); x = t; QuantifierBody(x, out typeParams, out ds, out kv, out trig, out e); if (typeParams.Count + ds.Count > 0) e = new ExistsExpr(x, typeParams, ds, kv, trig, e); } else if (la.kind == 93 || la.kind == 94) { Lambda(); x = t; QuantifierBody(x, out typeParams, out ds, out kv, out trig, out e); if (trig != null) SemErr("triggers not allowed in lambda expressions"); if (typeParams.Count + ds.Count > 0) e = new LambdaExpr(x, typeParams, ds, kv, e); } else SynErr(125); Expect(11); break; } case 41: { IfThenElseExpression(out e); break; } case 86: { CodeExpression(out locals, out blocks); e = new CodeExpr(locals, blocks); break; } default: SynErr(126); break; } }
public ActionInfo(Procedure proc, CodeExpr codeExpr, MoverType moverType, int phaseNum) { this.proc = proc; this.moverType = moverType; this.phaseNum = phaseNum; this.callerPhaseNums = new HashSet <int>(); this.thisGate = new List <AssertCmd>(); this.thisAction = codeExpr; this.thisInParams = new List <Variable>(); this.thisOutParams = new List <Variable>(); this.thatGate = new List <AssertCmd>(); this.thatInParams = new List <Variable>(); this.thatOutParams = new List <Variable>(); var cmds = thisAction.Blocks[0].Cmds; for (int i = 0; i < cmds.Count; i++) { AssertCmd assertCmd = cmds[i] as AssertCmd; if (assertCmd == null) { break; } thisGate.Add(assertCmd); cmds[i] = new AssumeCmd(assertCmd.tok, assertCmd.Expr); } Dictionary <Variable, Expr> map = new Dictionary <Variable, Expr>(); foreach (Variable x in proc.InParams) { this.thisInParams.Add(x); Variable y = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), true); this.thatInParams.Add(y); map[x] = new IdentifierExpr(Token.NoToken, y); } foreach (Variable x in proc.OutParams) { this.thisOutParams.Add(x); Variable y = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), false); this.thatOutParams.Add(y); map[x] = new IdentifierExpr(Token.NoToken, y); } List <Variable> otherLocVars = new List <Variable>(); foreach (Variable x in thisAction.LocVars) { Variable y = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), false); map[x] = new IdentifierExpr(Token.NoToken, y); otherLocVars.Add(y); } Contract.Assume(proc.TypeParameters.Count == 0); Substitution subst = Substituter.SubstitutionFromHashtable(map); foreach (AssertCmd assertCmd in thisGate) { thatGate.Add((AssertCmd)Substituter.Apply(subst, assertCmd)); } Dictionary <Block, Block> blockMap = new Dictionary <Block, Block>(); List <Block> otherBlocks = new List <Block>(); foreach (Block block in thisAction.Blocks) { List <Cmd> otherCmds = new List <Cmd>(); foreach (Cmd cmd in block.Cmds) { otherCmds.Add(Substituter.Apply(subst, cmd)); } Block otherBlock = new Block(); otherBlock.Cmds = otherCmds; otherBlock.Label = "that_" + block.Label; block.Label = "this_" + block.Label; otherBlocks.Add(otherBlock); blockMap[block] = otherBlock; if (block.TransferCmd is GotoCmd) { GotoCmd gotoCmd = block.TransferCmd as GotoCmd; for (int i = 0; i < gotoCmd.labelNames.Count; i++) { gotoCmd.labelNames[i] = "this_" + gotoCmd.labelNames[i]; } } } foreach (Block block in thisAction.Blocks) { if (block.TransferCmd is ReturnExprCmd) { block.TransferCmd = new ReturnCmd(block.TransferCmd.tok); blockMap[block].TransferCmd = new ReturnCmd(block.TransferCmd.tok); continue; } List <Block> otherGotoCmdLabelTargets = new List <Block>(); List <string> otherGotoCmdLabelNames = new List <string>(); GotoCmd gotoCmd = block.TransferCmd as GotoCmd; foreach (Block target in gotoCmd.labelTargets) { otherGotoCmdLabelTargets.Add(blockMap[target]); otherGotoCmdLabelNames.Add(blockMap[target].Label); } blockMap[block].TransferCmd = new GotoCmd(block.TransferCmd.tok, otherGotoCmdLabelNames, otherGotoCmdLabelTargets); } this.thatAction = new CodeExpr(otherLocVars, otherBlocks); }
public void TypeCheck() { foreach (var proc in program.Procedures) { if (!QKeyValue.FindBoolAttribute(proc.Attributes, "pure")) { continue; } if (QKeyValue.FindBoolAttribute(proc.Attributes, "yields")) { Error(proc, "Pure procedure must not yield"); continue; } if (QKeyValue.FindBoolAttribute(proc.Attributes, "layer")) { Error(proc, "Pure procedure must not have layers"); continue; } if (proc.Modifies.Count > 0) { Error(proc, "Pure procedure must not modify a global variable"); continue; } procToAtomicProcedureInfo[proc] = new AtomicProcedureInfo(); } foreach (var proc in program.Procedures) { if (QKeyValue.FindBoolAttribute(proc.Attributes, "yields")) { continue; } var procLayerNums = FindLayers(proc.Attributes); if (procLayerNums.Count == 0) { continue; } foreach (IdentifierExpr ie in proc.Modifies) { if (!globalVarToSharedVarInfo.ContainsKey(ie.Decl)) { Error(proc, "Atomic procedure cannot modify a global variable without layer numbers"); continue; } } int lower, upper; if (procLayerNums.Count == 1) { lower = procLayerNums[0]; upper = procLayerNums[0]; } else if (procLayerNums.Count == 2) { lower = procLayerNums[0]; upper = procLayerNums[1]; if (lower >= upper) { Error(proc, "Lower layer must be less than upper layer"); continue; } } else { Error(proc, "Atomic procedure must specify a layer range"); continue; } LayerRange layerRange = new LayerRange(lower, upper); procToAtomicProcedureInfo[proc] = new AtomicProcedureInfo(layerRange); } if (errorCount > 0) { return; } foreach (Implementation impl in program.Implementations) { if (!procToAtomicProcedureInfo.ContainsKey(impl.Proc)) { continue; } var atomicProcedureInfo = procToAtomicProcedureInfo[impl.Proc]; if (atomicProcedureInfo.isPure) { this.enclosingImpl = impl; (new PurityChecker(this)).VisitImplementation(impl); } else { this.enclosingImpl = impl; this.sharedVarsAccessed = new HashSet <Variable>(); (new PurityChecker(this)).VisitImplementation(impl); LayerRange upperBound = FindLayerRange(); LayerRange lowerBound = atomicProcedureInfo.layerRange; if (!lowerBound.Subset(upperBound)) { Error(impl, "Atomic procedure cannot access global variable"); } this.sharedVarsAccessed = null; } } if (errorCount > 0) { return; } foreach (var proc in program.Procedures) { if (!QKeyValue.FindBoolAttribute(proc.Attributes, "yields")) { continue; } int createdAtLayerNum; // must be initialized by the following code, otherwise it is an error int availableUptoLayerNum = int.MaxValue; List <int> attrs = FindLayers(proc.Attributes); if (attrs.Count == 1) { createdAtLayerNum = attrs[0]; } else if (attrs.Count == 2) { createdAtLayerNum = attrs[0]; availableUptoLayerNum = attrs[1]; } else { Error(proc, "Incorrect number of layers"); continue; } foreach (Ensures e in proc.Ensures) { MoverType moverType = GetMoverType(e); if (moverType == MoverType.Top) { continue; } CodeExpr codeExpr = e.Condition as CodeExpr; if (codeExpr == null) { Error(e, "An atomic action must be a CodeExpr"); continue; } if (procToActionInfo.ContainsKey(proc)) { Error(proc, "A procedure can have at most one atomic action"); continue; } if (availableUptoLayerNum <= createdAtLayerNum) { Error(proc, "Creation layer number must be less than the available upto layer number"); continue; } sharedVarsAccessed = new HashSet <Variable>(); enclosingProc = proc; enclosingImpl = null; base.VisitEnsures(e); LayerRange upperBound = FindLayerRange(); LayerRange lowerBound = new LayerRange(createdAtLayerNum, availableUptoLayerNum); if (lowerBound.Subset(upperBound)) { procToActionInfo[proc] = new AtomicActionInfo(proc, e, moverType, createdAtLayerNum, availableUptoLayerNum); } else { Error(e, "A variable being accessed in this action is unavailable"); } sharedVarsAccessed = null; } if (errorCount > 0) { continue; } if (!procToActionInfo.ContainsKey(proc)) { if (availableUptoLayerNum < createdAtLayerNum) { Error(proc, "Creation layer number must be no more than the available upto layer number"); continue; } else { procToActionInfo[proc] = new ActionInfo(proc, createdAtLayerNum, availableUptoLayerNum); } } } if (errorCount > 0) { return; } foreach (var impl in program.Implementations) { if (!procToActionInfo.ContainsKey(impl.Proc)) { continue; } ActionInfo actionInfo = procToActionInfo[impl.Proc]; procToActionInfo[impl.Proc].hasImplementation = true; if (actionInfo.isExtern) { Error(impl.Proc, "Extern procedure cannot have an implementation"); } } if (errorCount > 0) { return; } foreach (Procedure proc in procToActionInfo.Keys) { for (int i = 0; i < proc.InParams.Count; i++) { Variable v = proc.InParams[i]; var layer = FindLocalVariableLayer(proc, v, procToActionInfo[proc].createdAtLayerNum); if (layer == int.MinValue) { continue; } localVarToLocalVariableInfo[v] = new LocalVariableInfo(layer); } for (int i = 0; i < proc.OutParams.Count; i++) { Variable v = proc.OutParams[i]; var layer = FindLocalVariableLayer(proc, v, procToActionInfo[proc].createdAtLayerNum); if (layer == int.MinValue) { continue; } localVarToLocalVariableInfo[v] = new LocalVariableInfo(layer); } } foreach (Implementation node in program.Implementations) { if (!procToActionInfo.ContainsKey(node.Proc)) { continue; } foreach (Variable v in node.LocVars) { var layer = FindLocalVariableLayer(node, v, procToActionInfo[node.Proc].createdAtLayerNum); if (layer == int.MinValue) { continue; } localVarToLocalVariableInfo[v] = new LocalVariableInfo(layer); } for (int i = 0; i < node.Proc.InParams.Count; i++) { Variable v = node.Proc.InParams[i]; if (!localVarToLocalVariableInfo.ContainsKey(v)) { continue; } var layer = localVarToLocalVariableInfo[v].layer; localVarToLocalVariableInfo[node.InParams[i]] = new LocalVariableInfo(layer); } for (int i = 0; i < node.Proc.OutParams.Count; i++) { Variable v = node.Proc.OutParams[i]; if (!localVarToLocalVariableInfo.ContainsKey(v)) { continue; } var layer = localVarToLocalVariableInfo[v].layer; localVarToLocalVariableInfo[node.OutParams[i]] = new LocalVariableInfo(layer); } } if (errorCount > 0) { return; } this.VisitProgram(program); if (errorCount > 0) { return; } YieldTypeChecker.PerformYieldSafeCheck(this); new LayerEraser().VisitProgram(program); }
public override Expr VisitCodeExpr(CodeExpr node) { add(node); return(base.VisitCodeExpr(node)); }
public AtomicActionInfo(Procedure proc, Ensures ensures, MoverType moverType, int layerNum, int availableUptoLayerNum) : base(proc, layerNum, availableUptoLayerNum) { CodeExpr codeExpr = ensures.Condition as CodeExpr; this.ensures = ensures; this.moverType = moverType; this.thisGate = new List <AssertCmd>(); this.thisAction = codeExpr; this.thisInParams = new List <Variable>(); this.thisOutParams = new List <Variable>(); this.thatGate = new List <AssertCmd>(); this.thatInParams = new List <Variable>(); this.thatOutParams = new List <Variable>(); this.hasAssumeCmd = false; foreach (Block block in codeExpr.Blocks) { block.Cmds.ForEach(x => this.hasAssumeCmd = this.hasAssumeCmd || x is AssumeCmd); } var cmds = thisAction.Blocks[0].Cmds; for (int i = 0; i < cmds.Count; i++) { AssertCmd assertCmd = cmds[i] as AssertCmd; if (assertCmd == null) { break; } thisGate.Add(assertCmd); cmds[i] = new AssumeCmd(assertCmd.tok, Expr.True); } Dictionary <Variable, Expr> map = new Dictionary <Variable, Expr>(); foreach (Variable x in proc.InParams) { this.thisInParams.Add(x); Variable y = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), true, x.Attributes); this.thatInParams.Add(y); map[x] = Expr.Ident(y); } foreach (Variable x in proc.OutParams) { this.thisOutParams.Add(x); Variable y = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), false, x.Attributes); this.thatOutParams.Add(y); map[x] = Expr.Ident(y); } List <Variable> thatLocVars = new List <Variable>(); foreach (Variable x in thisAction.LocVars) { Variable y = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), false); map[x] = Expr.Ident(y); thatLocVars.Add(y); } Contract.Assume(proc.TypeParameters.Count == 0); Substitution subst = Substituter.SubstitutionFromHashtable(map); foreach (AssertCmd assertCmd in thisGate) { thatGate.Add((AssertCmd)Substituter.Apply(subst, assertCmd)); } Dictionary <Block, Block> blockMap = new Dictionary <Block, Block>(); List <Block> thatBlocks = new List <Block>(); foreach (Block block in thisAction.Blocks) { List <Cmd> otherCmds = new List <Cmd>(); foreach (Cmd cmd in block.Cmds) { otherCmds.Add(Substituter.Apply(subst, cmd)); } Block thatBlock = new Block(); thatBlock.Cmds = otherCmds; thatBlock.Label = "that_" + block.Label; block.Label = "this_" + block.Label; thatBlocks.Add(thatBlock); blockMap[block] = thatBlock; if (block.TransferCmd is GotoCmd) { GotoCmd gotoCmd = block.TransferCmd as GotoCmd; for (int i = 0; i < gotoCmd.labelNames.Count; i++) { gotoCmd.labelNames[i] = "this_" + gotoCmd.labelNames[i]; } } } foreach (Block block in thisAction.Blocks) { if (block.TransferCmd is ReturnExprCmd) { block.TransferCmd = new ReturnCmd(block.TransferCmd.tok); blockMap[block].TransferCmd = new ReturnCmd(block.TransferCmd.tok); continue; } List <Block> thatGotoCmdLabelTargets = new List <Block>(); List <string> thatGotoCmdLabelNames = new List <string>(); GotoCmd gotoCmd = block.TransferCmd as GotoCmd; foreach (Block target in gotoCmd.labelTargets) { thatGotoCmdLabelTargets.Add(blockMap[target]); thatGotoCmdLabelNames.Add(blockMap[target].Label); } blockMap[block].TransferCmd = new GotoCmd(block.TransferCmd.tok, thatGotoCmdLabelNames, thatGotoCmdLabelTargets); } this.thatAction = new CodeExpr(thatLocVars, thatBlocks); { VariableCollector collector = new VariableCollector(); collector.Visit(codeExpr); this.actionUsedGlobalVars = new HashSet <Variable>(collector.usedVars.Where(x => x is GlobalVariable)); } List <Variable> modifiedVars = new List <Variable>(); foreach (Block block in codeExpr.Blocks) { block.Cmds.ForEach(cmd => cmd.AddAssignedVariables(modifiedVars)); } this.modifiedGlobalVars = new HashSet <Variable>(modifiedVars.Where(x => x is GlobalVariable)); { VariableCollector collector = new VariableCollector(); this.thisGate.ForEach(assertCmd => collector.Visit(assertCmd)); this.gateUsedGlobalVars = new HashSet <Variable>(collector.usedVars.Where(x => x is GlobalVariable)); } }
//do not support code block expressions public override Expr VisitCodeExpr(CodeExpr node) { problematicNode = node; return(node); }
public AtomicActionInfo(Procedure proc, Ensures ensures, MoverType moverType, int layerNum, int availableUptoLayerNum) : base(proc, layerNum, availableUptoLayerNum) { this.ensures = ensures; this.moverType = moverType; this.gate = new List <AssertCmd>(); this.action = ensures.Condition as CodeExpr; this.thisGate = new List <AssertCmd>(); this.thisInParams = new List <Variable>(); this.thisOutParams = new List <Variable>(); this.thatGate = new List <AssertCmd>(); this.thatInParams = new List <Variable>(); this.thatOutParams = new List <Variable>(); this.hasAssumeCmd = false; this.thisMap = new Dictionary <Variable, Expr>(); this.thatMap = new Dictionary <Variable, Expr>(); foreach (Block block in this.action.Blocks) { block.Cmds.ForEach(x => this.hasAssumeCmd = this.hasAssumeCmd || x is AssumeCmd); } foreach (Block block in this.action.Blocks) { if (block.TransferCmd is ReturnExprCmd) { block.TransferCmd = new ReturnCmd(block.TransferCmd.tok); } } var cmds = this.action.Blocks[0].Cmds; for (int i = 0; i < cmds.Count; i++) { AssertCmd assertCmd = cmds[i] as AssertCmd; if (assertCmd == null) { break; } this.gate.Add(assertCmd); cmds[i] = new AssumeCmd(assertCmd.tok, Expr.True); } foreach (Variable x in proc.InParams) { Variable thisx = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "this_" + x.Name, x.TypedIdent.Type), true, x.Attributes); this.thisInParams.Add(thisx); this.thisMap[x] = Expr.Ident(thisx); Variable thatx = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), true, x.Attributes); this.thatInParams.Add(thatx); this.thatMap[x] = Expr.Ident(thatx); } foreach (Variable x in proc.OutParams) { Variable thisx = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "this_" + x.Name, x.TypedIdent.Type), false, x.Attributes); this.thisOutParams.Add(thisx); this.thisMap[x] = Expr.Ident(thisx); Variable thatx = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), false, x.Attributes); this.thatOutParams.Add(thatx); this.thatMap[x] = Expr.Ident(thatx); } List <Variable> thisLocVars = new List <Variable>(); List <Variable> thatLocVars = new List <Variable>(); foreach (Variable x in this.action.LocVars) { Variable thisx = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "this_" + x.Name, x.TypedIdent.Type), false); thisMap[x] = Expr.Ident(thisx); thisLocVars.Add(thisx); Variable thatx = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), false); thatMap[x] = Expr.Ident(thatx); thatLocVars.Add(thatx); } Contract.Assume(proc.TypeParameters.Count == 0); Substitution thisSubst = Substituter.SubstitutionFromHashtable(this.thisMap); Substitution thatSubst = Substituter.SubstitutionFromHashtable(this.thatMap); foreach (AssertCmd assertCmd in this.gate) { this.thisGate.Add((AssertCmd)Substituter.Apply(thisSubst, assertCmd)); this.thatGate.Add((AssertCmd)Substituter.Apply(thatSubst, assertCmd)); } this.thisAction = new CodeExpr(thisLocVars, SubstituteBlocks(this.action.Blocks, thisSubst, "this_")); this.thatAction = new CodeExpr(thatLocVars, SubstituteBlocks(this.action.Blocks, thatSubst, "that_")); { VariableCollector collector = new VariableCollector(); collector.Visit(this.action); this.actionUsedGlobalVars = new HashSet <Variable>(collector.usedVars.Where(x => x is GlobalVariable)); } List <Variable> modifiedVars = new List <Variable>(); foreach (Block block in this.action.Blocks) { block.Cmds.ForEach(cmd => cmd.AddAssignedVariables(modifiedVars)); } this.modifiedGlobalVars = new HashSet <Variable>(modifiedVars.Where(x => x is GlobalVariable)); { VariableCollector collector = new VariableCollector(); this.gate.ForEach(assertCmd => collector.Visit(assertCmd)); this.gateUsedGlobalVars = new HashSet <Variable>(collector.usedVars.Where(x => x is GlobalVariable)); } }
public void TypeCheck() { foreach (var proc in program.Procedures) { if (!QKeyValue.FindBoolAttribute(proc.Attributes, "yields")) { continue; } int createdAtLayerNum; // must be initialized by the following code, otherwise it is an error int availableUptoLayerNum = int.MaxValue; List <int> attrs = FindLayers(proc.Attributes); if (attrs.Count == 1) { createdAtLayerNum = attrs[0]; } else if (attrs.Count == 2) { createdAtLayerNum = attrs[0]; availableUptoLayerNum = attrs[1]; } else { Error(proc, "Incorrect number of layers"); continue; } foreach (Ensures e in proc.Ensures) { MoverType moverType = GetMoverType(e); if (moverType == MoverType.Top) { continue; } CodeExpr codeExpr = e.Condition as CodeExpr; if (codeExpr == null) { Error(e, "An atomic action must be a CodeExpr"); continue; } if (procToActionInfo.ContainsKey(proc)) { Error(proc, "A procedure can have at most one atomic action"); continue; } if (availableUptoLayerNum <= createdAtLayerNum) { Error(proc, "Creation layer number must be less than the available upto layer number"); continue; } minLayerNum = int.MaxValue; maxLayerNum = -1; canAccessSharedVars = true; enclosingProc = proc; enclosingImpl = null; base.VisitEnsures(e); canAccessSharedVars = false; if (maxLayerNum > createdAtLayerNum) { Error(e, "A variable being accessed is introduced after this action is created"); } else if (availableUptoLayerNum > minLayerNum) { Error(e, "A variable being accessed is hidden before this action becomes unavailable"); } else { procToActionInfo[proc] = new AtomicActionInfo(proc, e, moverType, createdAtLayerNum, availableUptoLayerNum); } } if (errorCount > 0) { continue; } if (!procToActionInfo.ContainsKey(proc)) { if (availableUptoLayerNum < createdAtLayerNum) { Error(proc, "Creation layer number must be no more than the available upto layer number"); continue; } else { procToActionInfo[proc] = new ActionInfo(proc, createdAtLayerNum, availableUptoLayerNum); } } } if (errorCount > 0) { return; } foreach (var impl in program.Implementations) { if (!procToActionInfo.ContainsKey(impl.Proc)) { continue; } procToActionInfo[impl.Proc].hasImplementation = true; } foreach (var proc in procToActionInfo.Keys) { ActionInfo actionInfo = procToActionInfo[proc]; if (actionInfo.isExtern && actionInfo.hasImplementation) { Error(proc, "Extern procedure cannot have an implementation"); continue; } if (actionInfo.isExtern || actionInfo.hasImplementation) { continue; } if (leastUnimplementedLayerNum == int.MaxValue) { leastUnimplementedLayerNum = actionInfo.createdAtLayerNum; } else if (leastUnimplementedLayerNum != actionInfo.createdAtLayerNum) { Error(proc, "All unimplemented atomic actions must be created at the same layer"); } } foreach (var g in this.globalVarToSharedVarInfo.Keys) { var info = globalVarToSharedVarInfo[g]; if (!this.AllCreatedLayerNums.Contains(info.introLayerNum)) { Error(g, "Variable must be introduced with creation of some atomic action"); } if (info.hideLayerNum != int.MaxValue && !this.AllCreatedLayerNums.Contains(info.hideLayerNum)) { Error(g, "Variable must be hidden with creation of some atomic action"); } } if (errorCount > 0) { return; } this.VisitProgram(program); foreach (Procedure proc in program.Procedures) { if (procToActionInfo.ContainsKey(proc)) { continue; } foreach (var ie in proc.Modifies) { if (!SharedVariables.Contains(ie.Decl)) { continue; } Error(proc, "A ghost procedure must not modify a global variable with layer annotation"); } } if (errorCount > 0) { return; } YieldTypeChecker.PerformYieldSafeCheck(this); new LayerEraser().VisitProgram(program); }
public override Expr VisitCodeExpr(CodeExpr node) { throw new NotImplementedException(); }
public AtomicActionInfo(Procedure proc, Ensures ensures, MoverType moverType, int layerNum, int availableUptoLayerNum) : base(proc, layerNum, availableUptoLayerNum) { CodeExpr codeExpr = ensures.Condition as CodeExpr; this.ensures = ensures; this.moverType = moverType; this.thisGate = new List<AssertCmd>(); this.thisAction = codeExpr; this.thisInParams = new List<Variable>(); this.thisOutParams = new List<Variable>(); this.thatGate = new List<AssertCmd>(); this.thatInParams = new List<Variable>(); this.thatOutParams = new List<Variable>(); this.hasAssumeCmd = false; foreach (Block block in codeExpr.Blocks) { block.Cmds.ForEach(x => this.hasAssumeCmd = this.hasAssumeCmd || x is AssumeCmd); } var cmds = thisAction.Blocks[0].Cmds; for (int i = 0; i < cmds.Count; i++) { AssertCmd assertCmd = cmds[i] as AssertCmd; if (assertCmd == null) break; thisGate.Add(assertCmd); cmds[i] = new AssumeCmd(assertCmd.tok, Expr.True); } Dictionary<Variable, Expr> map = new Dictionary<Variable, Expr>(); foreach (Variable x in proc.InParams) { this.thisInParams.Add(x); Variable y = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), true, x.Attributes); this.thatInParams.Add(y); map[x] = Expr.Ident(y); } foreach (Variable x in proc.OutParams) { this.thisOutParams.Add(x); Variable y = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), false, x.Attributes); this.thatOutParams.Add(y); map[x] = Expr.Ident(y); } List<Variable> thatLocVars = new List<Variable>(); foreach (Variable x in thisAction.LocVars) { Variable y = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), false); map[x] = Expr.Ident(y); thatLocVars.Add(y); } Contract.Assume(proc.TypeParameters.Count == 0); Substitution subst = Substituter.SubstitutionFromHashtable(map); foreach (AssertCmd assertCmd in thisGate) { thatGate.Add((AssertCmd)Substituter.Apply(subst, assertCmd)); } Dictionary<Block, Block> blockMap = new Dictionary<Block, Block>(); List<Block> thatBlocks = new List<Block>(); foreach (Block block in thisAction.Blocks) { List<Cmd> otherCmds = new List<Cmd>(); foreach (Cmd cmd in block.Cmds) { otherCmds.Add(Substituter.Apply(subst, cmd)); } Block thatBlock = new Block(); thatBlock.Cmds = otherCmds; thatBlock.Label = "that_" + block.Label; block.Label = "this_" + block.Label; thatBlocks.Add(thatBlock); blockMap[block] = thatBlock; if (block.TransferCmd is GotoCmd) { GotoCmd gotoCmd = block.TransferCmd as GotoCmd; for (int i = 0; i < gotoCmd.labelNames.Count; i++) { gotoCmd.labelNames[i] = "this_" + gotoCmd.labelNames[i]; } } } foreach (Block block in thisAction.Blocks) { if (block.TransferCmd is ReturnExprCmd) { block.TransferCmd = new ReturnCmd(block.TransferCmd.tok); blockMap[block].TransferCmd = new ReturnCmd(block.TransferCmd.tok); continue; } List<Block> thatGotoCmdLabelTargets = new List<Block>(); List<string> thatGotoCmdLabelNames = new List<string>(); GotoCmd gotoCmd = block.TransferCmd as GotoCmd; foreach (Block target in gotoCmd.labelTargets) { thatGotoCmdLabelTargets.Add(blockMap[target]); thatGotoCmdLabelNames.Add(blockMap[target].Label); } blockMap[block].TransferCmd = new GotoCmd(block.TransferCmd.tok, thatGotoCmdLabelNames, thatGotoCmdLabelTargets); } this.thatAction = new CodeExpr(thatLocVars, thatBlocks); { VariableCollector collector = new VariableCollector(); collector.Visit(codeExpr); this.actionUsedGlobalVars = new HashSet<Variable>(collector.usedVars.Where(x => x is GlobalVariable)); } List<Variable> modifiedVars = new List<Variable>(); foreach (Block block in codeExpr.Blocks) { block.Cmds.ForEach(cmd => cmd.AddAssignedVariables(modifiedVars)); } this.modifiedGlobalVars = new HashSet<Variable>(modifiedVars.Where(x => x is GlobalVariable)); { VariableCollector collector = new VariableCollector(); this.thisGate.ForEach(assertCmd => collector.Visit(assertCmd)); this.gateUsedGlobalVars = new HashSet<Variable>(collector.usedVars.Where(x => x is GlobalVariable)); } }
public override Expr VisitCodeExpr(CodeExpr node) { Contract.Ensures(Contract.Result<Expr>() == node); this.VisitVariableSeq(node.LocVars); this.VisitBlockList(node.Blocks); return node; }
public ActionInfo(Procedure proc, CodeExpr codeExpr, MoverType moverType, int phaseNum) { this.proc = proc; this.moverType = moverType; this.phaseNum = phaseNum; this.callerPhaseNums = new HashSet<int>(); this.thisGate = new List<AssertCmd>(); this.thisAction = codeExpr; this.thisInParams = new List<Variable>(); this.thisOutParams = new List<Variable>(); this.thatGate = new List<AssertCmd>(); this.thatInParams = new List<Variable>(); this.thatOutParams = new List<Variable>(); var cmds = thisAction.Blocks[0].Cmds; for (int i = 0; i < cmds.Count; i++) { AssertCmd assertCmd = cmds[i] as AssertCmd; if (assertCmd == null) break; thisGate.Add(assertCmd); cmds[i] = new AssumeCmd(assertCmd.tok, assertCmd.Expr); } Dictionary<Variable, Expr> map = new Dictionary<Variable, Expr>(); foreach (Variable x in proc.InParams) { this.thisInParams.Add(x); Variable y = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), true); this.thatInParams.Add(y); map[x] = new IdentifierExpr(Token.NoToken, y); } foreach (Variable x in proc.OutParams) { this.thisOutParams.Add(x); Variable y = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), false); this.thatOutParams.Add(y); map[x] = new IdentifierExpr(Token.NoToken, y); } List<Variable> otherLocVars = new List<Variable>(); foreach (Variable x in thisAction.LocVars) { Variable y = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), false); map[x] = new IdentifierExpr(Token.NoToken, y); otherLocVars.Add(y); } Contract.Assume(proc.TypeParameters.Count == 0); Substitution subst = Substituter.SubstitutionFromHashtable(map); foreach (AssertCmd assertCmd in thisGate) { thatGate.Add((AssertCmd)Substituter.Apply(subst, assertCmd)); } Dictionary<Block, Block> blockMap = new Dictionary<Block, Block>(); List<Block> otherBlocks = new List<Block>(); foreach (Block block in thisAction.Blocks) { List<Cmd> otherCmds = new List<Cmd>(); foreach (Cmd cmd in block.Cmds) { otherCmds.Add(Substituter.Apply(subst, cmd)); } Block otherBlock = new Block(); otherBlock.Cmds = otherCmds; otherBlock.Label = "that_" + block.Label; block.Label = "this_" + block.Label; otherBlocks.Add(otherBlock); blockMap[block] = otherBlock; if (block.TransferCmd is GotoCmd) { GotoCmd gotoCmd = block.TransferCmd as GotoCmd; for (int i = 0; i < gotoCmd.labelNames.Count; i++) { gotoCmd.labelNames[i] = "this_" + gotoCmd.labelNames[i]; } } } foreach (Block block in thisAction.Blocks) { if (block.TransferCmd is ReturnExprCmd) { block.TransferCmd = new ReturnCmd(block.TransferCmd.tok); blockMap[block].TransferCmd = new ReturnCmd(block.TransferCmd.tok); continue; } List<Block> otherGotoCmdLabelTargets = new List<Block>(); List<string> otherGotoCmdLabelNames = new List<string>(); GotoCmd gotoCmd = block.TransferCmd as GotoCmd; foreach (Block target in gotoCmd.labelTargets) { otherGotoCmdLabelTargets.Add(blockMap[target]); otherGotoCmdLabelNames.Add(blockMap[target].Label); } blockMap[block].TransferCmd = new GotoCmd(block.TransferCmd.tok, otherGotoCmdLabelNames, otherGotoCmdLabelTargets); } this.thatAction = new CodeExpr(otherLocVars, otherBlocks); }
public Expr VisitCodeExpr(CodeExpr e) { throw new NotImplementedException(); }
public override Expr VisitCodeExpr(CodeExpr node) { // don't recurse on subexpression return node; }
public override Expr VisitCodeExpr(CodeExpr node) { // don't go into the code expression, since it can only modify variables local to the code expression, // and the mod-set analysis is interested in global variables return node; }