context: /*
      Hypergraph objects
      Copyright (C) 2008 Bob Mottram
      fuzzgun@gmail.com
  
      This program is free software: you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published by
      the Free Software Foundation, either version 3 of the License, or
      (at your option) any later version.
  
      This program is distributed in the hope that it will be useful,
      but WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      GNU General Public License for more details.
  
      You should have received a copy of the GNU General Public License
      along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
  
  using System;
  using System.IO;
  using System.Collections.Generic;
  
  namespace surveyor.vision
  {
      /// <summary>
      /// represents a link between nodes in a graph
      /// </summary>
      public class hypergraph_link
      {
          public hypergraph_node From;
          public hypergraph_node To;
      }
      
      /// <summary>
      /// represents a graph node
      /// </summary>
      public class hypergraph_node
      {
          public string Name;
          public int ID;
          public List<hypergraph_link> Links;
          public List<bool> Flags;        
          
          public hypergraph_node(int no_of_flags)
          {
              Flags = new List<bool>();
              for (int i = 0; i < no_of_flags; i++) Flags.Add(false);
              Links = new List<hypergraph_link>();
          }
          
          public void Add(hypergraph_link link)
          {
              Links.Add(link);
          }
          
          public void Clear()
          {
              Links.Clear();
              Flags.Clear();
          }
          
          /// <summary>
          /// return the link with the given from ID
          /// </summary>
          /// <param name="from_ID">ID to search for</param>
          /// <returns>link object (null if not found)</returns>
          public hypergraph_link GetLink(int from_ID)
          {
              hypergraph_link lnk = null;
  
              int i = 0;
              while ((i < Links.Count) && (lnk == null))
              {
                  if (Links[i] != null)
                      if (Links[i].From.ID == from_ID) lnk = Links[i];
                  i++;
              }
              return (lnk);
          }        
      }
      
      /// <summary>
      /// represents a set of nodes and links
      /// </summary>
      public class hypergraph
      {
          public List<hypergraph_node> Nodes;
          public List<hypergraph_link> Links;
          
          #region "constructors"        
          
          public hypergraph()
          {
              Nodes = new List<hypergraph_node>();
              Links = new List<hypergraph_link>();
          }
  
          public hypergraph(int no_of_nodes, int no_of_flags)
          {
              Nodes = new List<hypergraph_node>();
              Links = new List<hypergraph_link>();
              for (int i = 0; i < no_of_nodes; i++)
              {
                  hypergraph_node node = new hypergraph_node(no_of_flags);
                  node.ID = i;
                  node.Name = i.ToString();
                  Add(node);
              }
          }
          
          #endregion
          
          #region "adding and removing nodes"        
          
          public void Add(hypergraph_node node)
          {
              Nodes.Add(node);
          }
          
          public void Remove(hypergraph_node node)
          {
              Nodes.Remove(node);
          }
          
          public void Remove(int ID)
          {
              int index = IndexOf(ID);
              if (index > -1) Nodes.RemoveAt(index);
          }
  
          public void Remove(string name)
          {
              int index = IndexOf(name);
              if (index > -1) Nodes.RemoveAt(index);
          }
          
          #endregion
  
          #region "getting nodes"
          
          public int IndexOf(int ID)
          {
              int index = -1;
              int i = 0;
              while ((i < Nodes.Count) && (index == -1))
              {
                  if (Nodes[i].ID == ID) index = i;
                  i++;
              }
              return(index);
          }
  
          public int IndexOf(string name)
          {
              int index = -1;
              int i = 0;
              while ((i < Nodes.Count) && (index == -1))
              {
                  if (Nodes[i].Name == name) index = i;
                  i++;
              }
              return(index);
          }
          
          public hypergraph_node GetNode(int ID)
          {
              hypergraph_node node = null;
              int index = IndexOf(ID);
              if (index > -1) node = Nodes[index];
              return(node);
          }
  
          public hypergraph_node GetNode(string name)
          {
              hypergraph_node node = null;
              int index = IndexOf(name);
              if (index > -1) node = Nodes[index];
              return(node);
          }
          
          #endregion
  
          #region "creating links between nodes"
  
          public bool LinkExists(hypergraph_node from_node, hypergraph_node to_node)
          {
              bool exists = false;
              
              if ((from_node != null) && (to_node != null))
              {
                  int i = 0;
                  while ((i < to_node.Links.Count) && (!exists))
                  {
                      if (to_node.Links[i] != null)
                          if (to_node.Links[i].From != null)
                              if (to_node.Links[i].From == from_node) exists = true;
                      i++;
                  }
              }
              return (exists);
          }
                  
          public void LinkByIndex(int from_node_index, int to_node_index)
          {
              hypergraph_link link = new hypergraph_link();
  
gt:             link.From = Nodes[from_node_index];