private IEnumerable <Variable> FilterInParams(IEnumerable <Variable> locals) { Predicate <LinearKind> isLinear = x => x == LinearKind.LINEAR || x == LinearKind.LINEAR_IN; return(locals.Where(v => isLinear(linearTypeChecker.FindLinearKind(v)) && civlTypeChecker.LocalVariableLayerRange(v).Contains(layerNum))); }
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(AtomicAction first, AtomicAction second) { if (first == second && first.firstImpl.InParams.Count == 0 && first.firstImpl.OutParams.Count == 0) { return; } if (first.TriviallyCommutesWith(second)) { return; } if (!commutativityCheckerCache.Add(Tuple.Create(first, second))) { return; } string checkerName = $"CommutativityChecker_{first.proc.Name}_{second.proc.Name}"; 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> { DisjointnessRequires( first.firstImpl.InParams.Union(second.secondImpl.InParams) .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 witnesses = civlTypeChecker.commutativityHints.GetWitnesses(first, second); var transitionRelation = TransitionRelationComputation.Commutativity(second, first, frame, witnesses); List <Cmd> cmds = new List <Cmd> { new CallCmd(Token.NoToken, first.proc.Name, first.firstImpl.InParams.Select(Expr.Ident).ToList <Expr>(), first.firstImpl.OutParams.Select(Expr.Ident).ToList() ) { Proc = first.proc }, new CallCmd(Token.NoToken, second.proc.Name, second.secondImpl.InParams.Select(Expr.Ident).ToList <Expr>(), second.secondImpl.OutParams.Select(Expr.Ident).ToList() ) { Proc = second.proc } }; foreach (var lemma in civlTypeChecker.commutativityHints.GetLemmas(first, second)) { cmds.Add(CmdHelper.AssumeCmd(ExprHelper.FunctionCall(lemma.function, lemma.args.ToArray()))); } var block = new Block(Token.NoToken, "init", cmds, new ReturnCmd(Token.NoToken)); var secondInParamsFiltered = second.secondImpl.InParams.Where(v => linearTypeChecker.FindLinearKind(v) != LinearKind.LINEAR_IN); IEnumerable <Expr> linearityAssumes = Enumerable.Union( linearTypeChecker.DisjointnessExprForEachDomain(first.firstImpl.OutParams.Union(secondInParamsFiltered) .Union(frame)), linearTypeChecker.DisjointnessExprForEachDomain(first.firstImpl.OutParams.Union(second.secondImpl.OutParams) .Union(frame))); // TODO: add further disjointness expressions? Ensures ensureCheck = new Ensures(first.proc.tok, false, Expr.Imp(Expr.And(linearityAssumes), transitionRelation), null) { ErrorData = $"Commutativity check between {first.proc.Name} and {second.proc.Name} failed" }; List <Ensures> ensures = new List <Ensures> { ensureCheck }; List <Variable> inputs = Enumerable.Union(first.firstImpl.InParams, second.secondImpl.InParams).ToList(); List <Variable> outputs = Enumerable.Union(first.firstImpl.OutParams, second.secondImpl.OutParams).ToList(); AddChecker(checkerName, inputs, outputs, new List <Variable>(), requires, ensures, new List <Block> { block }); }
private static List<Expr> PendingAsyncLinearParams(LinearTypeChecker linearTypeChecker, LinearDomain domain, AtomicAction pendingAsync, IdentifierExpr pa) { var pendingAsyncLinearParams = new List<Expr>(); for (int i = 0; i < pendingAsync.proc.InParams.Count; i++) { var inParam = pendingAsync.proc.InParams[i]; if (linearTypeChecker.FindDomainName(inParam) == domain.domainName && InKinds.Contains(linearTypeChecker.FindLinearKind(inParam))) { var pendingAsyncParam = ExprHelper.FunctionCall(pendingAsync.pendingAsyncCtor.selectors[i], pa); pendingAsyncLinearParams.Add(pendingAsyncParam); } } return pendingAsyncLinearParams; }
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); }
private IEnumerable <Variable> Filter(IEnumerable <Variable> locals, Predicate <LinearKind> pred) { return(locals.Where(v => pred(linearTypeChecker.FindLinearKind(v)) && civlTypeChecker.LocalVariableLayerRange(v).Contains(layerNum))); }