private void CreateCommutativityChecker(Program program, AtomicActionInfo first, AtomicActionInfo second) { if (first == second && first.thatInParams.Count == 0 && first.thatOutParams.Count == 0) { return; } if (first.CommutesWith(second)) { return; } if (!commutativityCheckerCache.Add(new Tuple <AtomicActionInfo, AtomicActionInfo>(first, second))) { return; } List <Variable> inputs = Enumerable.Union(first.thatInParams, second.thisInParams).ToList(); List <Variable> outputs = Enumerable.Union(first.thatOutParams, second.thisOutParams).ToList(); List <Variable> locals = Enumerable.Union(first.thatAction.LocVars, second.thisAction.LocVars).ToList(); List <Block> firstBlocks = CloneBlocks(first.thatAction.Blocks); List <Block> secondBlocks = CloneBlocks(second.thisAction.Blocks); foreach (Block b in firstBlocks.Where(b => b.TransferCmd is ReturnCmd)) { List <Block> bs = new List <Block> { secondBlocks[0] }; List <string> ls = new List <string> { secondBlocks[0].Label }; b.TransferCmd = new GotoCmd(Token.NoToken, ls, bs); } List <Block> blocks = Enumerable.Union(firstBlocks, secondBlocks).ToList(); HashSet <Variable> frame = new HashSet <Variable>(); frame.UnionWith(first.gateUsedGlobalVars); frame.UnionWith(first.actionUsedGlobalVars); frame.UnionWith(second.gateUsedGlobalVars); frame.UnionWith(second.actionUsedGlobalVars); List <Requires> requires = new List <Requires>(); requires.Add(DisjointnessRequires(program, first.thatInParams.Union(second.thisInParams), frame)); foreach (AssertCmd assertCmd in Enumerable.Union(first.thatGate, second.thisGate)) { requires.Add(new Requires(false, assertCmd.Expr)); } var transitionRelationComputation = new TransitionRelationComputation(program, first, second, frame, new HashSet <Variable>()); Expr transitionRelation = transitionRelationComputation.TransitionRelationCompute(); { List <Block> bs = new List <Block> { blocks[0] }; List <string> ls = new List <string> { blocks[0].Label }; var initBlock = new Block(Token.NoToken, string.Format("{0}_{1}_init", first.proc.Name, second.proc.Name), transitionRelationComputation.TriggerAssumes(), new GotoCmd(Token.NoToken, ls, bs)); blocks.Insert(0, initBlock); } var thisInParamsFiltered = second.thisInParams.Where(v => linearTypeChecker.FindLinearKind(v) != LinearKind.LINEAR_IN); IEnumerable <Expr> linearityAssumes = Enumerable.Union( DisjointnessExpr(program, first.thatOutParams.Union(thisInParamsFiltered), frame), DisjointnessExpr(program, first.thatOutParams.Union(second.thisOutParams), frame)); // TODO: add further disjointness expressions? Ensures ensureCheck = new Ensures(false, Expr.Imp(Expr.And(linearityAssumes), transitionRelation)); ensureCheck.ErrorData = string.Format("Commutativity check between {0} and {1} failed", first.proc.Name, second.proc.Name); List <Ensures> ensures = new List <Ensures> { ensureCheck }; string checkerName = string.Format("CommutativityChecker_{0}_{1}", first.proc.Name, second.proc.Name); List <IdentifierExpr> globalVars = civlTypeChecker.SharedVariables.Select(x => Expr.Ident(x)).ToList(); Procedure proc = new Procedure(Token.NoToken, checkerName, new List <TypeVariable>(), inputs, outputs, requires, globalVars, ensures); Implementation impl = new Implementation(Token.NoToken, checkerName, new List <TypeVariable>(), inputs, outputs, locals, blocks); impl.Proc = proc; this.decls.Add(impl); this.decls.Add(proc); }
private void CreateCommutativityChecker(Program program, AtomicActionInfo first, AtomicActionInfo second) { if (first == second && first.thatInParams.Count == 0 && first.thatOutParams.Count == 0) return; if (first.CommutesWith(second)) return; if (!commutativityCheckerCache.Add(new Tuple<AtomicActionInfo, AtomicActionInfo>(first, second))) return; List<Variable> inputs = Enumerable.Union(first.thatInParams, second.thisInParams).ToList(); List<Variable> outputs = Enumerable.Union(first.thatOutParams, second.thisOutParams).ToList(); List<Variable> locals = Enumerable.Union(first.thatAction.LocVars, second.thisAction.LocVars).ToList(); List<Block> firstBlocks = CloneBlocks(first.thatAction.Blocks); List<Block> secondBlocks = CloneBlocks(second.thisAction.Blocks); foreach (Block b in firstBlocks.Where(b => b.TransferCmd is ReturnCmd)) { List<Block> bs = new List<Block> { secondBlocks[0] }; List<string> ls = new List<string> { secondBlocks[0].Label }; b.TransferCmd = new GotoCmd(Token.NoToken, ls, bs); } List<Block> blocks = Enumerable.Union(firstBlocks, secondBlocks).ToList(); HashSet<Variable> frame = new HashSet<Variable>(); frame.UnionWith(first.gateUsedGlobalVars); frame.UnionWith(first.actionUsedGlobalVars); frame.UnionWith(second.gateUsedGlobalVars); frame.UnionWith(second.actionUsedGlobalVars); List<Requires> requires = new List<Requires>(); requires.Add(DisjointnessRequires(program, first.thatInParams.Union(second.thisInParams), frame)); foreach (AssertCmd assertCmd in Enumerable.Union(first.thatGate, second.thisGate)) requires.Add(new Requires(false, assertCmd.Expr)); var transitionRelationComputation = new TransitionRelationComputation(program, first, second, frame, new HashSet<Variable>()); Expr transitionRelation = transitionRelationComputation.TransitionRelationCompute(); { List<Block> bs = new List<Block> { blocks[0] }; List<string> ls = new List<string> { blocks[0].Label }; var initBlock = new Block(Token.NoToken, string.Format("{0}_{1}_init", first.proc.Name, second.proc.Name), transitionRelationComputation.TriggerAssumes(), new GotoCmd(Token.NoToken, ls, bs)); blocks.Insert(0, initBlock); } IEnumerable<Expr> linearityAssumes = DisjointnessExpr(program, first.thatOutParams.Union(second.thisInParams), frame).Union(DisjointnessExpr(program, first.thatOutParams.Union(second.thisOutParams), frame)); Ensures ensureCheck = new Ensures(false, Expr.Imp(Expr.And(linearityAssumes), transitionRelation)); ensureCheck.ErrorData = string.Format("Commutativity check between {0} and {1} failed", first.proc.Name, second.proc.Name); List<Ensures> ensures = new List<Ensures> { ensureCheck }; string checkerName = string.Format("CommutativityChecker_{0}_{1}", first.proc.Name, second.proc.Name); List<IdentifierExpr> globalVars = civlTypeChecker.SharedVariables.Select(x => Expr.Ident(x)).ToList(); Procedure proc = new Procedure(Token.NoToken, checkerName, new List<TypeVariable>(), inputs, outputs, requires, globalVars, ensures); Implementation impl = new Implementation(Token.NoToken, checkerName, new List<TypeVariable>(), inputs, outputs, locals, blocks); impl.Proc = proc; this.decls.Add(impl); this.decls.Add(proc); }
private void CreateCommutativityChecker(Program program, AtomicActionInfo first, AtomicActionInfo second) { if (first == second && first.thatInParams.Count == 0 && first.thatOutParams.Count == 0) { return; } if (first.CommutesWith(second)) { return; } Tuple <AtomicActionInfo, AtomicActionInfo> actionPair = new Tuple <AtomicActionInfo, AtomicActionInfo>(first, second); if (commutativityCheckerCache.Contains(actionPair)) { return; } commutativityCheckerCache.Add(actionPair); List <Variable> inputs = new List <Variable>(); inputs.AddRange(first.thatInParams); inputs.AddRange(second.thisInParams); List <Variable> outputs = new List <Variable>(); outputs.AddRange(first.thatOutParams); outputs.AddRange(second.thisOutParams); List <Variable> locals = new List <Variable>(); locals.AddRange(first.thatAction.LocVars); locals.AddRange(second.thisAction.LocVars); List <Block> firstBlocks = CloneBlocks(first.thatAction.Blocks); List <Block> secondBlocks = CloneBlocks(second.thisAction.Blocks); foreach (Block b in firstBlocks) { if (b.TransferCmd is ReturnCmd) { List <Block> bs = new List <Block>(); bs.Add(secondBlocks[0]); List <string> ls = new List <string>(); ls.Add(secondBlocks[0].Label); b.TransferCmd = new GotoCmd(Token.NoToken, ls, bs); } } List <Block> blocks = new List <Block>(); blocks.AddRange(firstBlocks); blocks.AddRange(secondBlocks); HashSet <Variable> frame = new HashSet <Variable>(); frame.UnionWith(first.gateUsedGlobalVars); frame.UnionWith(first.actionUsedGlobalVars); frame.UnionWith(second.gateUsedGlobalVars); frame.UnionWith(second.actionUsedGlobalVars); List <Requires> requires = DisjointnessRequires(program, first, second, frame); foreach (AssertCmd assertCmd in first.thatGate) { requires.Add(new Requires(false, assertCmd.Expr)); } foreach (AssertCmd assertCmd in second.thisGate) { requires.Add(new Requires(false, assertCmd.Expr)); } List <Ensures> ensures = new List <Ensures>(); Expr transitionRelation = (new TransitionRelationComputation(program, first, second, frame, new HashSet <Variable>())).TransitionRelationCompute(); Ensures ensureCheck = new Ensures(false, transitionRelation); ensureCheck.ErrorData = string.Format("Commutativity check between {0} and {1} failed", first.proc.Name, second.proc.Name); ensures.Add(ensureCheck); string checkerName = string.Format("CommutativityChecker_{0}_{1}", first.proc.Name, second.proc.Name); List <IdentifierExpr> globalVars = new List <IdentifierExpr>(); moverTypeChecker.SharedVariables.Iter(x => globalVars.Add(Expr.Ident(x))); Procedure proc = new Procedure(Token.NoToken, checkerName, new List <TypeVariable>(), inputs, outputs, requires, globalVars, ensures); Implementation impl = new Implementation(Token.NoToken, checkerName, new List <TypeVariable>(), inputs, outputs, locals, blocks); impl.Proc = proc; this.decls.Add(impl); this.decls.Add(proc); }
private void CreateCommutativityChecker(Program program, AtomicActionInfo first, AtomicActionInfo second) { if (first == second && first.thatInParams.Count == 0 && first.thatOutParams.Count == 0) return; if (first.CommutesWith(second)) return; Tuple<AtomicActionInfo, AtomicActionInfo> actionPair = new Tuple<AtomicActionInfo, AtomicActionInfo>(first, second); if (commutativityCheckerCache.Contains(actionPair)) return; commutativityCheckerCache.Add(actionPair); List<Variable> inputs = new List<Variable>(); inputs.AddRange(first.thatInParams); inputs.AddRange(second.thisInParams); List<Variable> outputs = new List<Variable>(); outputs.AddRange(first.thatOutParams); outputs.AddRange(second.thisOutParams); List<Variable> locals = new List<Variable>(); locals.AddRange(first.thatAction.LocVars); locals.AddRange(second.thisAction.LocVars); List<Block> firstBlocks = CloneBlocks(first.thatAction.Blocks); List<Block> secondBlocks = CloneBlocks(second.thisAction.Blocks); foreach (Block b in firstBlocks) { if (b.TransferCmd is ReturnCmd) { List<Block> bs = new List<Block>(); bs.Add(secondBlocks[0]); List<string> ls = new List<string>(); ls.Add(secondBlocks[0].Label); b.TransferCmd = new GotoCmd(Token.NoToken, ls, bs); } } List<Block> blocks = new List<Block>(); blocks.AddRange(firstBlocks); blocks.AddRange(secondBlocks); HashSet<Variable> frame = new HashSet<Variable>(); frame.UnionWith(first.gateUsedGlobalVars); frame.UnionWith(first.actionUsedGlobalVars); frame.UnionWith(second.gateUsedGlobalVars); frame.UnionWith(second.actionUsedGlobalVars); List<Requires> requires = DisjointnessRequires(program, first, second, frame); foreach (AssertCmd assertCmd in first.thatGate) requires.Add(new Requires(false, assertCmd.Expr)); foreach (AssertCmd assertCmd in second.thisGate) requires.Add(new Requires(false, assertCmd.Expr)); List<Ensures> ensures = new List<Ensures>(); Expr transitionRelation = (new TransitionRelationComputation(program, first, second, frame, new HashSet<Variable>())).TransitionRelationCompute(); Ensures ensureCheck = new Ensures(false, transitionRelation); ensureCheck.ErrorData = string.Format("Commutativity check between {0} and {1} failed", first.proc.Name, second.proc.Name); ensures.Add(ensureCheck); string checkerName = string.Format("CommutativityChecker_{0}_{1}", first.proc.Name, second.proc.Name); List<IdentifierExpr> globalVars = new List<IdentifierExpr>(); civlTypeChecker.SharedVariables.Iter(x => globalVars.Add(Expr.Ident(x))); Procedure proc = new Procedure(Token.NoToken, checkerName, new List<TypeVariable>(), inputs, outputs, requires, globalVars, ensures); Implementation impl = new Implementation(Token.NoToken, checkerName, new List<TypeVariable>(), inputs, outputs, locals, blocks); impl.Proc = proc; this.decls.Add(impl); this.decls.Add(proc); }