internal CandidateReachabilityChecker(Program prog, IEnumerable <string> candidates)
        {
            this.prog                  = prog;
            this.candidates            = candidates;
            this.reachabilityGraph     = new InterproceduralReachabilityGraph(prog);
            this.candidateToOccurences = new Dictionary <string, HashSet <object> >();

            // Add all candidate occurrences in blocks
            foreach (Block b in prog.TopLevelDeclarations.OfType <Implementation>().Select(Item => Item.Blocks).SelectMany(Item => Item))
            {
                foreach (Cmd cmd in b.Cmds)
                {
                    AssertCmd assertCmd = cmd as AssertCmd;
                    if (assertCmd != null)
                    {
                        string c;
                        if (Houdini.MatchCandidate(assertCmd.Expr, candidates, out c))
                        {
                            AddCandidateOccurrence(c, b);
                        }
                    }
                }
            }

            // Add all candidate occurrences in preconditions
            foreach (var proc in prog.TopLevelDeclarations.OfType <Procedure>())
            {
                foreach (Requires r in proc.Requires)
                {
                    string c;
                    if (Houdini.MatchCandidate(r.Condition, candidates, out c))
                    {
                        AddCandidateOccurrence(c, new Tuple <string, PrePost>(proc.Name, PrePost.PRE));
                    }
                }
            }

            // Add all candidate occurrences in preconditions
            foreach (var proc in prog.TopLevelDeclarations.OfType <Procedure>())
            {
                foreach (Ensures e in proc.Ensures)
                {
                    string c;
                    if (Houdini.MatchCandidate(e.Condition, candidates, out c))
                    {
                        AddCandidateOccurrence(c, new Tuple <string, PrePost>(proc.Name, PrePost.POST));
                    }
                }
            }
        }
        internal AnnotationReachabilityChecker(Program prog, IEnumerable <string> AnnotationIdentifiers)
        {
            this.prog = prog;
            this.AnnotationIdentifiers  = AnnotationIdentifiers;
            this.reachabilityGraph      = new InterproceduralReachabilityGraph(prog);
            this.annotationToOccurences = new Dictionary <string, HashSet <object> >();

            // Add all annotation occurrences in blocks
            foreach (Block b in prog.Blocks())
            {
                foreach (var assertCmd in b.Cmds.OfType <AssertCmd>())
                {
                    string c;
                    if (Houdini.MatchCandidate(assertCmd.Expr, AnnotationIdentifiers, out c))
                    {
                        AddAnnotationOccurrence(c, b);
                    }
                    else
                    {
                        var tag = AnnotationDependenceAnalyser.GetTagFromNonCandidateAttributes(assertCmd.Attributes);
                        if (tag != null)
                        {
                            AddAnnotationOccurrence(tag, b);
                        }
                    }
                }
            }

            // Add all annotation occurrences in pre and post conditions
            foreach (var proc in prog.NonInlinedProcedures())
            {
                foreach (Requires r in proc.Requires)
                {
                    string c;
                    if (Houdini.MatchCandidate(r.Condition, AnnotationIdentifiers, out c))
                    {
                        AddAnnotationOccurrence(c, new Tuple <string, PrePost>(proc.Name, PrePost.PRE));
                    }
                    else
                    {
                        string tag = AnnotationDependenceAnalyser.GetTagFromNonCandidateAttributes(r.Attributes);
                        if (tag != null)
                        {
                            AddAnnotationOccurrence(tag, new Tuple <string, PrePost>(proc.Name, PrePost.PRE));
                        }
                    }
                }

                foreach (Ensures e in proc.Ensures)
                {
                    string c;
                    if (Houdini.MatchCandidate(e.Condition, AnnotationIdentifiers, out c))
                    {
                        AddAnnotationOccurrence(c, new Tuple <string, PrePost>(proc.Name, PrePost.POST));
                    }
                    else
                    {
                        string tag = AnnotationDependenceAnalyser.GetTagFromNonCandidateAttributes(e.Attributes);
                        if (tag != null)
                        {
                            AddAnnotationOccurrence(tag, new Tuple <string, PrePost>(proc.Name, PrePost.PRE));
                        }
                    }
                }
            }
        }
        internal CandidateReachabilityChecker(Program prog, IEnumerable<string> candidates)
        {
            this.prog = prog;
              this.candidates = candidates;
              this.reachabilityGraph = new InterproceduralReachabilityGraph(prog);
              this.candidateToOccurences = new Dictionary<string,HashSet<object>>();

              // Add all candidate occurrences in blocks
              foreach(Block b in prog.TopLevelDeclarations.OfType<Implementation>().Select(Item => Item.Blocks).SelectMany(Item => Item)) {
            foreach(Cmd cmd in b.Cmds) {
              AssertCmd assertCmd = cmd as AssertCmd;
              if(assertCmd != null) {
            string c;
            if(Houdini.MatchCandidate(assertCmd.Expr, candidates, out c)) {
              AddCandidateOccurrence(c, b);
            }
              }
            }
              }

              // Add all candidate occurrences in preconditions
              foreach(var proc in prog.TopLevelDeclarations.OfType<Procedure>()) {
            foreach(Requires r in proc.Requires) {
              string c;
              if(Houdini.MatchCandidate(r.Condition, candidates, out c)) {
            AddCandidateOccurrence(c, new Tuple<string, PrePost>(proc.Name, PrePost.PRE));
              }
            }
              }

              // Add all candidate occurrences in preconditions
              foreach(var proc in prog.TopLevelDeclarations.OfType<Procedure>()) {
            foreach(Ensures e in proc.Ensures) {
              string c;
              if(Houdini.MatchCandidate(e.Condition, candidates, out c)) {
            AddCandidateOccurrence(c, new Tuple<string, PrePost>(proc.Name, PrePost.POST));
              }
            }
              }
        }
    internal AnnotationReachabilityChecker(Program prog, IEnumerable<string> AnnotationIdentifiers) {
      this.prog = prog;
      this.AnnotationIdentifiers = AnnotationIdentifiers;
      this.reachabilityGraph = new InterproceduralReachabilityGraph(prog);
      this.annotationToOccurences = new Dictionary<string,HashSet<object>>();

      // Add all annotation occurrences in blocks
      foreach(Block b in prog.Blocks()) {
        foreach(var assertCmd in b.Cmds.OfType<AssertCmd>()) {
          string c;
          if(Houdini.MatchCandidate(assertCmd.Expr, AnnotationIdentifiers, out c)) {
            AddAnnotationOccurrence(c, b);
          } else {
            var tag = AnnotationDependenceAnalyser.GetTagFromNonCandidateAttributes(assertCmd.Attributes);
            if (tag != null) {
              AddAnnotationOccurrence(tag, b);
            }
          }
        }
      }

      // Add all annotation occurrences in pre and post conditions
      foreach(var proc in prog.NonInlinedProcedures()) {
        foreach(Requires r in proc.Requires) {
          string c;
          if(Houdini.MatchCandidate(r.Condition, AnnotationIdentifiers, out c)) {
            AddAnnotationOccurrence(c, new Tuple<string, PrePost>(proc.Name, PrePost.PRE));
          } else {
            string tag = AnnotationDependenceAnalyser.GetTagFromNonCandidateAttributes(r.Attributes);
            if(tag != null) {
              AddAnnotationOccurrence(tag, new Tuple<string, PrePost>(proc.Name, PrePost.PRE));
            }
          }
        }
        foreach(Ensures e in proc.Ensures) {
          string c;
          if(Houdini.MatchCandidate(e.Condition, AnnotationIdentifiers, out c)) {
            AddAnnotationOccurrence(c, new Tuple<string, PrePost>(proc.Name, PrePost.POST));
          } else {
            string tag = AnnotationDependenceAnalyser.GetTagFromNonCandidateAttributes(e.Attributes);
            if(tag != null) {
              AddAnnotationOccurrence(tag, new Tuple<string, PrePost>(proc.Name, PrePost.PRE));
            }
          }
        }
      }
      
    }