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; } 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(AtomicActionCopy first, AtomicActionCopy second) { if (first == second && first.firstInParams.Count == 0 && first.firstOutParams.Count == 0) { return; } if (first.TriviallyCommutesWith(second)) { return; } if (!commutativityCheckerCache.Add(Tuple.Create(first, second))) { return; } List <Variable> inputs = Enumerable.Union(first.firstInParams, second.secondInParams).ToList(); List <Variable> outputs = Enumerable.Union(first.firstOutParams, second.secondOutParams).ToList(); List <Variable> locals = Enumerable.Union(first.firstAction.LocVars, second.secondAction.LocVars).ToList(); List <Block> blocks = ComposeBlocks(first, second); 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(first.firstInParams.Union(second.secondInParams).Where(v => linearTypeChecker.FindLinearKind(v) != LinearKind.LINEAR_OUT), frame)); foreach (AssertCmd assertCmd in Enumerable.Union(first.firstGate, second.secondGate)) { requires.Add(new Requires(false, assertCmd.Expr)); } var transitionRelationComputation = new TransitionRelationComputation(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 secondInParamsFiltered = second.secondInParams.Where(v => linearTypeChecker.FindLinearKind(v) != LinearKind.LINEAR_IN); IEnumerable <Expr> linearityAssumes = Enumerable.Union( DisjointnessExpr(first.firstOutParams.Union(secondInParamsFiltered), frame), DisjointnessExpr(first.firstOutParams.Union(second.secondOutParams), frame)); // TODO: add further disjointness expressions? Ensures ensureCheck = new Ensures(first.proc.tok, false, Expr.Imp(Expr.And(linearityAssumes), transitionRelation), null); 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); AddChecker(checkerName, inputs, outputs, locals, requires, ensures, blocks); }