Example #1
0
        public void Transform()
        {
            foreach (var decl in program.TopLevelDeclarations)
            {
                Implementation impl = decl as Implementation;
                if (impl == null)
                {
                    continue;
                }
                Dictionary <string, Variable> domainNameToInputVar = new Dictionary <string, Variable>();
                foreach (string domainName in linearDomains.Keys)
                {
                    var    domain = linearDomains[domainName];
                    Formal f      = new Formal(
                        Token.NoToken,
                        new TypedIdent(Token.NoToken,
                                       "linear_" + domainName + "_in",
                                       new MapType(Token.NoToken, new List <TypeVariable>(),
                                                   new List <Type> {
                        domain.elementType
                    }, Type.Bool)), true);
                    impl.InParams.Add(f);
                    domainNameToInputVar[domainName] = f;
                }

                foreach (Block b in impl.Blocks)
                {
                    List <Cmd> newCmds = new List <Cmd>();
                    for (int i = 0; i < b.Cmds.Count; i++)
                    {
                        Cmd cmd = b.Cmds[i];
                        newCmds.Add(cmd);
                        if (cmd is CallCmd)
                        {
                            CallCmd callCmd = cmd as CallCmd;
                            if (callCmd.IsAsync)
                            {
                                foreach (var domainName in linearDomains.Keys)
                                {
                                    var domain = linearDomains[domainName];
                                    var expr   = new NAryExpr(Token.NoToken, new FunctionCall(domain.mapConstBool), new List <Expr> {
                                        Expr.False
                                    });
                                    expr.Resolve(new ResolutionContext(null));
                                    expr.Typecheck(new TypecheckingContext(null));
                                    callCmd.Ins.Add(expr);
                                }
                            }
                            else
                            {
                                Dictionary <string, Expr> domainNameToExpr = new Dictionary <string, Expr>();
                                foreach (var domainName in linearDomains.Keys)
                                {
                                    domainNameToExpr[domainName] = new IdentifierExpr(Token.NoToken, domainNameToInputVar[domainName]);
                                }
                                foreach (Variable v in availableLinearVars[callCmd])
                                {
                                    var            domainName = FindDomainName(v);
                                    var            domain     = linearDomains[domainName];
                                    IdentifierExpr ie         = new IdentifierExpr(Token.NoToken, v);
                                    var            expr       = new NAryExpr(Token.NoToken, new FunctionCall(domain.mapOrBool),
                                                                             new List <Expr> {
                                        v.TypedIdent.Type is MapType ? ie : Singleton(ie, domainName), domainNameToExpr[domainName]
                                    });
                                    expr.Resolve(new ResolutionContext(null));
                                    expr.Typecheck(new TypecheckingContext(null));
                                    domainNameToExpr[domainName] = expr;
                                }
                                foreach (var domainName in linearDomains.Keys)
                                {
                                    callCmd.Ins.Add(domainNameToExpr[domainName]);
                                }
                            }
                        }
                        else if (cmd is ParCallCmd)
                        {
                            ParCallCmd parCallCmd = (ParCallCmd)cmd;
                            foreach (CallCmd callCmd in parCallCmd.CallCmds)
                            {
                                foreach (var domainName in linearDomains.Keys)
                                {
                                    var domain = linearDomains[domainName];
                                    var expr   = new NAryExpr(Token.NoToken, new FunctionCall(domain.mapConstBool), new List <Expr> {
                                        Expr.False
                                    });
                                    expr.Resolve(new ResolutionContext(null));
                                    expr.Typecheck(new TypecheckingContext(null));
                                    callCmd.Ins.Add(expr);
                                }
                            }
                        }
                        else if (cmd is YieldCmd)
                        {
                            AddDisjointnessExpr(newCmds, cmd, domainNameToInputVar);
                        }
                    }
                    b.Cmds = newCmds;
                }

                {
                    // Loops
                    impl.PruneUnreachableBlocks();
                    impl.ComputePredecessorsForBlocks();
                    GraphUtil.Graph <Block> g = Program.GraphFromImpl(impl);
                    g.ComputeLoops();
                    if (g.Reducible)
                    {
                        foreach (Block header in g.Headers)
                        {
                            List <Cmd> newCmds = new List <Cmd>();
                            AddDisjointnessExpr(newCmds, header, domainNameToInputVar);
                            newCmds.AddRange(header.Cmds);
                            header.Cmds = newCmds;
                        }
                    }
                }
            }

            foreach (var decl in program.TopLevelDeclarations)
            {
                Procedure proc = decl as Procedure;
                if (proc == null)
                {
                    continue;
                }

                Dictionary <string, HashSet <Variable> > domainNameToInputScope  = new Dictionary <string, HashSet <Variable> >();
                Dictionary <string, HashSet <Variable> > domainNameToOutputScope = new Dictionary <string, HashSet <Variable> >();
                foreach (var domainName in linearDomains.Keys)
                {
                    domainNameToInputScope[domainName]  = new HashSet <Variable>();
                    domainNameToOutputScope[domainName] = new HashSet <Variable>();
                }
                foreach (Variable v in globalVarToDomainName.Keys)
                {
                    var domainName = globalVarToDomainName[v];
                    domainNameToInputScope[domainName].Add(v);
                    domainNameToOutputScope[domainName].Add(v);
                }
                foreach (Variable v in proc.InParams)
                {
                    var domainName = FindDomainName(v);
                    if (domainName == null)
                    {
                        continue;
                    }
                    domainNameToInputScope[domainName].Add(v);
                }
                foreach (Variable v in proc.OutParams)
                {
                    var domainName = FindDomainName(v);
                    if (domainName == null)
                    {
                        continue;
                    }
                    domainNameToOutputScope[domainName].Add(v);
                }
                foreach (var domainName in linearDomains.Keys)
                {
                    proc.Requires.Add(new Requires(true, DisjointnessExpr(domainName, domainNameToInputScope[domainName])));
                    var    domain = linearDomains[domainName];
                    Formal f      = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "linear_" + domainName + "_in", new MapType(Token.NoToken, new List <TypeVariable>(), new List <Type> {
                        domain.elementType
                    }, Type.Bool)), true);
                    proc.InParams.Add(f);
                    domainNameToOutputScope[domainName].Add(f);
                    proc.Ensures.Add(new Ensures(true, DisjointnessExpr(domainName, domainNameToOutputScope[domainName])));
                }
            }

            foreach (LinearDomain domain in linearDomains.Values)
            {
                program.TopLevelDeclarations.Add(domain.mapConstBool);
                program.TopLevelDeclarations.Add(domain.mapConstInt);
                program.TopLevelDeclarations.Add(domain.mapEqInt);
                program.TopLevelDeclarations.Add(domain.mapImpBool);
                program.TopLevelDeclarations.Add(domain.mapOrBool);
                foreach (Axiom axiom in domain.axioms)
                {
                    program.TopLevelDeclarations.Add(axiom);
                }
            }

            //int oldPrintUnstructured = CommandLineOptions.Clo.PrintUnstructured;
            //CommandLineOptions.Clo.PrintUnstructured = 1;
            //PrintBplFile("lsd.bpl", program, false, false);
            //CommandLineOptions.Clo.PrintUnstructured = oldPrintUnstructured;
        }
Example #2
0
    public override Implementation VisitImplementation(Implementation node)
    {
      if (civlTypeChecker.procToAtomicAction.ContainsKey(node.Proc) ||
          civlTypeChecker.procToIntroductionAction.ContainsKey(node.Proc) ||
          civlTypeChecker.procToLemmaProc.ContainsKey(node.Proc))
        return node;

      node.PruneUnreachableBlocks();
      node.ComputePredecessorsForBlocks();
      GraphUtil.Graph<Block> graph = Program.GraphFromImpl(node);
      graph.ComputeLoops();

      HashSet<Variable> start = new HashSet<Variable>(globalVarToDomainName.Keys);
      for (int i = 0; i < node.InParams.Count; i++)
      {
        Variable v = node.Proc.InParams[i];
        string domainName = FindDomainName(v);
        if (domainName != null)
        {
          var kind = FindLinearKind(v);
          inParamToLinearQualifier[node.InParams[i]] = new LinearQualifier(domainName, kind);
          if (kind == LinearKind.LINEAR || kind == LinearKind.LINEAR_IN)
          {
            start.Add(node.InParams[i]);
          }
        }
      }

      for (int i = 0; i < node.OutParams.Count; i++)
      {
        string domainName = FindDomainName(node.Proc.OutParams[i]);
        if (domainName != null)
        {
          outParamToDomainName[node.OutParams[i]] = domainName;
        }
      }

      var oldErrorCount = checkingContext.ErrorCount;
      var impl = base.VisitImplementation(node);
      if (oldErrorCount < checkingContext.ErrorCount)
        return impl;

      Stack<Block> dfsStack = new Stack<Block>();
      HashSet<Block> dfsStackAsSet = new HashSet<Block>();
      availableLinearVars[node.Blocks[0]] = start;
      dfsStack.Push(node.Blocks[0]);
      dfsStackAsSet.Add(node.Blocks[0]);
      while (dfsStack.Count > 0)
      {
        Block b = dfsStack.Pop();
        dfsStackAsSet.Remove(b);
        HashSet<Variable> end = PropagateAvailableLinearVarsAcrossBlock(b);
        if (b.TransferCmd is ReturnCmd)
        {
          foreach (GlobalVariable g in globalVarToDomainName.Keys.Except(end))
          {
            Error(b.TransferCmd, $"Global variable {g.Name} must be available at a return");
          }

          foreach (Variable v in node.InParams)
          {
            if (FindDomainName(v) == null || FindLinearKind(v) == LinearKind.LINEAR_IN || end.Contains(v)) continue;
            Error(b.TransferCmd, $"Input variable {v.Name} must be available at a return");
          }

          foreach (Variable v in node.OutParams)
          {
            if (FindDomainName(v) == null || end.Contains(v)) continue;
            Error(b.TransferCmd, $"Output variable {v.Name} must be available at a return");
          }

          continue;
        }

        GotoCmd gotoCmd = b.TransferCmd as GotoCmd;
        foreach (Block target in gotoCmd.labelTargets)
        {
          if (!availableLinearVars.ContainsKey(target))
          {
            availableLinearVars[target] = new HashSet<Variable>(end);
            dfsStack.Push(target);
            dfsStackAsSet.Add(target);
          }
          else
          {
            var savedAvailableVars = new HashSet<Variable>(availableLinearVars[target]);
            availableLinearVars[target].IntersectWith(end);
            if (savedAvailableVars.IsProperSupersetOf(availableLinearVars[target]) && !dfsStackAsSet.Contains(target))
            {
              dfsStack.Push(target);
              dfsStackAsSet.Add(target);
            }
          }
        }
      }

      if (graph.Reducible)
      {
        foreach (Block header in graph.Headers)
        {
          foreach (GlobalVariable g in globalVarToDomainName.Keys.Except(availableLinearVars[header]))
          {
            Error(header, $"Global variable {g.Name} must be available at a loop head");
          }
        }
      }

      return impl;
    }
Example #3
0
    private void PrepareCommon()
    {
      if (common.Length == 0)
      {
        SendCommon("(set-option :print-success false)");
        SendCommon("(set-info :smt-lib-version 2.0)");
        if (options.ProduceModel())
          SendCommon("(set-option :produce-models true)");
        foreach (var opt in options.SmtOptions)
        {
          SendCommon("(set-option :" + opt.Option + " " + opt.Value + ")");
        }

        if (!string.IsNullOrEmpty(options.Logic))
        {
          SendCommon("(set-logic " + options.Logic + ")");
        }

        // Set produce-unsat-cores last. It seems there's a bug in Z3 where if we set it earlier its value
        // gets reset by other set-option commands ( https://z3.codeplex.com/workitem/188 )
        if (CommandLineOptions.Clo.PrintNecessaryAssumes || (CommandLineOptions.Clo.ContractInfer && (CommandLineOptions.Clo.UseUnsatCoreForContractInfer || CommandLineOptions.Clo.ExplainHoudini)))
        {
          SendCommon("(set-option :produce-unsat-cores true)");
          this.usingUnsatCore = true;
        }

        SendCommon("; done setting options\n");
        SendCommon(_backgroundPredicates);

        if (options.UseTickleBool)
        {
          SendCommon("(declare-fun tickleBool (Bool) Bool)");
          SendCommon("(assert (and (tickleBool true) (tickleBool false)))");
        }

        if (CommandLineOptions.Clo.RunDiagnosticsOnTimeout)
        {
          SendCommon("(declare-fun timeoutDiagnostics (Int) Bool)");
        }

        if (ctx.KnownDatatypeConstructors.Count > 0)
        {
          GraphUtil.Graph<CtorType> dependencyGraph = new GraphUtil.Graph<CtorType>();
          foreach (CtorType datatype in ctx.KnownDatatypeConstructors.Keys)
          {
            dependencyGraph.AddSource(datatype);
            foreach (Function f in ctx.KnownDatatypeConstructors[datatype])
            {
              List<CtorType> dependentTypes = new List<CtorType>();
              foreach (Variable v in f.InParams)
              {
                FindDependentTypes(v.TypedIdent.Type, dependentTypes);
              }
              foreach (CtorType result in dependentTypes)
              {
                dependencyGraph.AddEdge(datatype, result);
              }
            }
          }
          GraphUtil.StronglyConnectedComponents<CtorType> sccs = new GraphUtil.StronglyConnectedComponents<CtorType>(dependencyGraph.Nodes, dependencyGraph.Predecessors, dependencyGraph.Successors);
          sccs.Compute();
          foreach (GraphUtil.SCC<CtorType> scc in sccs)
          {
            string datatypeString = "";
            foreach (CtorType datatype in scc)
            {
              datatypeString += "(" + SMTLibExprLineariser.TypeToString(datatype) + " ";
              foreach (Function f in ctx.KnownDatatypeConstructors[datatype])
              {
                string quotedConstructorName = Namer.GetQuotedName(f, f.Name);
                if (f.InParams.Count == 0)
                {
                  datatypeString += quotedConstructorName + " ";
                }
                else
                {
                  datatypeString += "(" + quotedConstructorName + " ";
                  foreach (Variable v in f.InParams)
                  {
                    string quotedSelectorName = Namer.GetQuotedName(v, v.Name + "#" + f.Name);
                    datatypeString += "(" + quotedSelectorName + " " + DeclCollector.TypeToStringReg(v.TypedIdent.Type) + ") ";
                  }
                  datatypeString += ") ";
                }
              }
              datatypeString += ") ";
            }
            List<string> decls = DeclCollector.GetNewDeclarations();
            foreach (string decl in decls)
            {
              SendCommon(decl);
            }
            SendCommon("(declare-datatypes () (" + datatypeString + "))");
          }
        }
        if (CommandLineOptions.Clo.ProverPreamble != null)
            SendCommon("(include \"" + CommandLineOptions.Clo.ProverPreamble + "\")");
      }

      if (!AxiomsAreSetup)
      {
        var axioms = ctx.Axioms;
        var nary = axioms as VCExprNAry;
        if (nary != null && nary.Op == VCExpressionGenerator.AndOp)
          foreach (var expr in nary.UniformArguments)
          {
            var str = VCExpr2String(expr, -1);
            if (str != "true")
              AddAxiom(str);
          }
        else
          AddAxiom(VCExpr2String(axioms, -1));
        AxiomsAreSetup = true;
      }
    }
Example #4
0
        private void PrepareCommon()
        {
            if (common.Length == 0)
              {
            SendCommon("(set-option :print-success false)");
            SendCommon("(set-info :smt-lib-version 2.0)");
            if (options.ProduceModel())
              SendCommon("(set-option :produce-models true)");
            foreach (var opt in options.SmtOptions)
            {
              SendCommon("(set-option :" + opt.Option + " " + opt.Value + ")");
            }

            if (!string.IsNullOrEmpty(options.Logic))
            {
              SendCommon("(set-logic " + options.Logic + ")");
            }

            SendCommon("; done setting options\n");
            SendCommon(_backgroundPredicates);

            if (options.UseTickleBool)
            {
              SendCommon("(declare-fun tickleBool (Bool) Bool)");
              SendCommon("(assert (and (tickleBool true) (tickleBool false)))");
            }

            if (ctx.KnownDatatypeConstructors.Count > 0)
            {
              GraphUtil.Graph<CtorType> dependencyGraph = new GraphUtil.Graph<CtorType>();
              foreach (CtorType datatype in ctx.KnownDatatypeConstructors.Keys)
              {
            dependencyGraph.AddSource(datatype);
            foreach (Function f in ctx.KnownDatatypeConstructors[datatype])
            {
              List<CtorType> dependentTypes = new List<CtorType>();
              foreach (Variable v in f.InParams)
              {
                FindDependentTypes(v.TypedIdent.Type, dependentTypes);
              }
              foreach (CtorType result in dependentTypes)
              {
                dependencyGraph.AddEdge(datatype, result);
              }
            }
              }
              GraphUtil.StronglyConnectedComponents<CtorType> sccs = new GraphUtil.StronglyConnectedComponents<CtorType>(dependencyGraph.Nodes, dependencyGraph.Predecessors, dependencyGraph.Successors);
              sccs.Compute();
              foreach (GraphUtil.SCC<CtorType> scc in sccs)
              {
            string datatypeString = "";
            foreach (CtorType datatype in scc)
            {
              datatypeString += "(" + SMTLibExprLineariser.TypeToString(datatype) + " ";
              foreach (Function f in ctx.KnownDatatypeConstructors[datatype])
              {
                string quotedConstructorName = Namer.GetQuotedName(f, f.Name);
                if (f.InParams.Count == 0)
                {
                  datatypeString += quotedConstructorName + " ";
                }
                else
                {
                  datatypeString += "(" + quotedConstructorName + " ";
                  foreach (Variable v in f.InParams)
                  {
                    string quotedSelectorName = Namer.GetQuotedName(v, v.Name + "#" + f.Name);
                    datatypeString += "(" + quotedSelectorName + " " + DeclCollector.TypeToStringReg(v.TypedIdent.Type) + ") ";
                  }
                  datatypeString += ") ";
                }
              }
              datatypeString += ") ";
            }
            List<string> decls = DeclCollector.GetNewDeclarations();
            foreach (string decl in decls)
            {
              SendCommon(decl);
            }
            SendCommon("(declare-datatypes () (" + datatypeString + "))");
              }
            }
              }

              if (!AxiomsAreSetup)
              {
            var axioms = ctx.Axioms;
            var nary = axioms as VCExprNAry;
            if (nary != null && nary.Op == VCExpressionGenerator.AndOp)
              foreach (var expr in nary.UniformArguments)
              {
            var str = VCExpr2String(expr, -1);
            if (str != "true")
              AddAxiom(str);
              }
            else
              AddAxiom(VCExpr2String(axioms, -1));
            AxiomsAreSetup = true;
              }
        }