title: Try to answer some boolean queries using Term-Document-Incidence-Matrix
body: <p>I try answer some simple boolean query in these ways <code>NOT x NOT y NOT z</code> also <code>x AND y AND z</code> and also like this <code>x OR y OR z</code> <code>x,y,z</code> are some words and any of them belongs to a different <code>file.txt</code>or maybe all of them belongs to same <code>file.txt</code>, no matter .</p>
  
  <p>I've written a <code>class TermDocMatrix</code>:</p>
  
  <p>it must be able to answer a boolean query , I prepared some methods in <code>class TermDocMatrix{ }</code>for these purposes but it doesn't work. I even debug the code step by step, I realized loops have no turn. I don't know why, codes seems fine.</p>
  
  <p>well you can see code in here :</p>
  
  <pre><code>class TermDocMatrix
  {
      //stores distinct terms
      public HashSet&lt;string&gt; distinctTerm = new HashSet&lt;string&gt;();
      //stores document id and its contents without splitting
      public Dictionary&lt;int, string&gt; documentContentList = new Dictionary&lt;int, string&gt;();
      //stores document and its terms collection
      public Dictionary&lt;string, List&lt;string&gt;&gt; documentCollection = new Dictionary&lt;string, List&lt;string&gt;&gt;();
      public Dictionary&lt;string, List&lt;int&gt;&gt; termDocumentIncidenceMatrix = new Dictionary&lt;string, List&lt;int&gt;&gt;();
  
       //stop words collection
      public List&lt;string&gt; stopWords = new List&lt;string&gt; { "on", "of", "The", "an", "a", "in" };
      //boolean operators list
      public string[] booleanOperator = new string[] { "AND", "OR", "NOT" };
  
      private string _FileName = "words";
      public string _Path = "";
      int _lastDocNum = 0;
  
      public TermDocMatrix(string IndexPath,string FileName)
      {
  
          if (_Path.EndsWith("\\") == false) _Path += "\\";
          if (!Directory.Exists(IndexPath)) Directory.CreateDirectory(IndexPath);
          LogManager.Configure(_Path + _FileName + ".txt", false);
          // read all files
          LoadFiles();
      }
  
      private void LoadFiles()
      {
          int count = 0;
  
          if (File.Exists(_Path + _FileName + ".txt") == false)
              return;
          // load words
          string b = File.ReadAllText(_Path + _FileName + ".txt");
          String[] TermsCollection = RemoveStopsWords(b.ToUpper().Split(' '));
          foreach (string term in TermsCollection)
          {
              //prepeare distinct terms collection
              //remove stop words
              if (!stopWords.Contains(term))
              {
                  distinctTerm.Add(term);
              }
          }
          //add document and their terms collection
          documentCollection.Add(_FileName, TermsCollection.ToList());
          //add document and its content for displaying the search result
          documentContentList.Add(count, b);
          count++;
      }
      public string ProcessFiles(string query)
      {
          termDocumentIncidenceMatrix = GetTermDocumentIncidenceMatrix(distinctTerm, documentCollection);
          do
          {
              List&lt;int&gt; lst = ProcessQuery(query);
              int count = 0;
              if (lst != null)
              {
                  foreach (int a in lst)
                  {
                      if (a == 1)
                      {
                           return documentContentList[count];
                      }
                      count++;
                  }
              }
              else
              {
                  return "No search result found";
              }
  
          } while (1 == 1);
      }
      public int WordCount()
      {
          return documentCollection.Count;
      }
  
      public int DocumentCount
      {
          get
          {
              return _lastDocNum;
          }
      }
  
      private void FilterQueryTerm(ref string[] str)
      {
          List&lt;string&gt; _queryTerm = new List&lt;string&gt;();
  
  
          foreach (string queryTerm in str)
          {
              if (queryTerm.ToUpper().Equals("BUT") || termDocumentIncidenceMatrix.ContainsKey(queryTerm.ToUpper()) || booleanOperator.Contains(queryTerm))
              {
                  _queryTerm.Add(queryTerm);
  
              }
          }
  
          str = _queryTerm.ToArray();
      }
  
      //prepares Term Document Incidence Matrix
      public Dictionary&lt;string, List&lt;int&gt;&gt; GetTermDocumentIncidenceMatrix(HashSet&lt;string&gt; distinctTerms, Dictionary&lt;string, List&lt;string&gt;&gt; documentCollection)
      {
          Dictionary&lt;string, List&lt;int&gt;&gt; termDocumentIncidenceMatrix = new Dictionary&lt;string, List&lt;int&gt;&gt;();
          List&lt;int&gt; incidenceVector = new List&lt;int&gt;();
          foreach (string term in distinctTerms)
          {
              //incidence vector for each terms
              incidenceVector = new List&lt;int&gt;();
              foreach (KeyValuePair&lt;string, List&lt;string&gt;&gt; p in documentCollection)
              {
  
                  if (p.Value.Contains(term))
                  {
                      //document contains the term
                      incidenceVector.Add(1);
  
                  }
                  else
                  {
                      //document do not contains the term
                      incidenceVector.Add(0);
                  }
              }
              termDocumentIncidenceMatrix.Add(term, incidenceVector);
  
          }
          return termDocumentIncidenceMatrix;
      }
      //removes all stop words
      public string[] RemoveStopsWords(string[] str)
      {
          List&lt;string&gt; terms = new List&lt;string&gt;();
          foreach (string term in str)
          {
              if (!stopWords.Contains(term))
              {
                  terms.Add(term);
              }
          }
          return terms.ToArray();
      }
      //process the boolean query
      public List&lt;int&gt; ProcessQuery(string query)
      {
  
          //query boolean operator
          string bitWiseOp = string.Empty;
          string[] queryTerm = RemoveStopsWords(query.ToUpper().Split(' '));
  
          //remove query term that doesnot appears on document collection
          FilterQueryTerm(ref queryTerm);
          List&lt;int&gt; previousTermIncidenceV = null;
          List&lt;int&gt; nextTermsIncidenceV = null;
          //holds the bitwise operation result
          List&lt;int&gt; resultSet = null;
          //suppose on query X AND Y, X is previousTerm term and Y is nextTerm
          Boolean hasPreviousTerm = false;
          Boolean hasNotOperation = false;
          foreach (string term in queryTerm)
          {
              //is a term
              if (!booleanOperator.Contains(term) &amp;&amp; !term.Equals("BUT"))
              {
                  //query case: structure AND NOT analysis
                  if (hasNotOperation)
                  {
  
                      if (hasPreviousTerm)
                      {
                          nextTermsIncidenceV = ProcessBooleanOperator("NOT", GetTermIncidenceVector(term), nextTermsIncidenceV);
                      }
                      //query case: eg.NOT analysis
                      else
                      {
                          previousTermIncidenceV = ProcessBooleanOperator("NOT", GetTermIncidenceVector(term), nextTermsIncidenceV);
                          resultSet = previousTermIncidenceV;
                      }
                      hasNotOperation = false;
                  }
                  else if (!hasPreviousTerm)
                  {
                      previousTermIncidenceV = GetTermIncidenceVector(term);
                      resultSet = previousTermIncidenceV;
                      hasPreviousTerm = true;
                  }
                  else
                  {
  
                      nextTermsIncidenceV = GetTermIncidenceVector(term);
                  }
              }
              else if (term.Equals("NOT"))
              {
                  //indicates that the  term in the next iteration should be complemented.
                  hasNotOperation = true;
              }
              else
              {
                  //'BUT' also should be evaluated as AND eg. structure BUT NOT semantic should be evaluated as structure AND NOT semantic
                  if (term.Equals("BUT"))
                  {
                      bitWiseOp = "AND";
                  }
                  else
                      bitWiseOp = term;
              }
  
              if (nextTermsIncidenceV != null &amp;&amp; !hasNotOperation)
              {
                  resultSet = ProcessBooleanOperator(bitWiseOp, previousTermIncidenceV, nextTermsIncidenceV);
                  previousTermIncidenceV = resultSet;
                  hasPreviousTerm = true;
                  nextTermsIncidenceV = null;
              }
          }
  
          return resultSet;
      }
  
      //Process Boolean operators
      public List&lt;int&gt; ProcessBooleanOperator(string op, List&lt;int&gt; previousTermV, List&lt;int&gt; nextTermV)
      {
          List&lt;int&gt; resultSet = new List&lt;int&gt;();
          if (op.Equals("NOT"))
          {
              foreach (int a in previousTermV)
              {
                  if (a == 1)
                  {
                      resultSet.Add(0);
                  }
                  else
                  {
                      resultSet.Add(1);
                  }
              }
          }
          else if (op.ToUpper().Equals("AND")) //bitwise AND operation
          {
              for (int a = 0; a &lt; previousTermV.Count; a++)
              {
                  if (previousTermV[a] == 1 &amp;&amp; nextTermV[a] == 1)
                  {
                      resultSet.Add(1);
                  }
                  else
                  {
                      resultSet.Add(0);
                  }
              }
          }
          else if (op.ToUpper().Equals("OR")) //bitwise OR operation
          {
              for (int a = 0; a &lt; previousTermV.Count; a++)
              {
                  if (previousTermV[a] == 0 &amp;&amp; nextTermV[a] == 0)
                  {
                      resultSet.Add(0);
                  }
                  else
                  {
                      resultSet.Add(1);
                  }
              }
          }
          return resultSet;
      }
  
      //returns term incidence vector
      public List&lt;int&gt; GetTermIncidenceVector(string term)
      {
          return termDocumentIncidenceMatrix[term.ToUpper()];
  
      }
  }
  </code></pre>
  
  <p>you need to now about another class named <code>Class LogManager</code> I used it on my <code>Class TermDocMatrix</code>.  Here :</p>
  
  <pre><code>namespace WindowsFormsApplication1
   {
     internal class FileLogger
     {
      public static readonly FileLogger Instance = new FileLogger();
  
      private string _filename;
      private bool _showMethodName = false;
      private string _FilePath = "";
  
      public bool ShowMethodNames
      {
          get { return _showMethodName; }
      }
  
      public void Init(string filename, bool showmethodnames)
      {
          _showMethodName = showmethodnames;
          _filename = filename;
          // handle folder names as well -&gt; create dir etc.
          _FilePath = Path.GetDirectoryName(filename);
          if (_FilePath != "")
          {
              _FilePath = Directory.CreateDirectory(_FilePath).FullName;
              if (_FilePath.EndsWith("\\") == false)
                  _FilePath += "\\";
          }
      }
  }
  internal static class LogManager
  {
  
      public static void Configure(string filename, bool showmethodnames)
      {
          FileLogger.Instance.Init(filename, showmethodnames);
      }
  }
  </code></pre>
  
  <p>}</p>
  
  <p>it must work but it don't. tell me why don't it work, please. when I ask for answer I just see this "No search result found", no matter I'd typed what kind of boolean query.</p>