using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using miew.BitArray;
namespace agree
{
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
///
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public abstract partial class GlbDag : Instance
{
public GlbDag(TypeMgr mgr, String name, List<BaseFeatConstraint> bfc)
: base(mgr, name, bfc)
{
}
public int m_id;
public ushort m_level;
public BitArr m_code;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
protected HashSet<Type> i_parents = new HashSet<Type>();
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
protected HashSet<Type> i_children = new HashSet<Type>();
public ushort FindLevel()
{
if (m_level == 0 && this != tm.TopType)
{
if (i_children.Count == 0)
m_flags |= Flags.Leaf;
m_level = (ushort)(i_parents.Max(p => p.FindLevel()) + 1);
}
return m_level;
}
public int ChildCount { get { return i_children.Count; } }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
///
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public bool IsGlb { get { return (m_flags & Flags.GlbType) > 0; } }
/// <summary>
/// leaf types have no children. They may have appropriate features
/// </summary>
public bool IsLeaf { get { return (m_flags & Flags.Leaf) > 0; } }
public void AddIParent(Type p)
{
i_parents.Add(p);
p.i_children.Add((Type)this);
}
public void RemoveIParent(Type p)
{
p.i_children.Remove((Type)this);
i_parents.Remove(p);
}
public void AddIChild(Type c)
{
if (c == this)
return;
i_children.Add(c);
c.i_parents.Add((Type)this);
}
public void RemoveIChild(Type c)
{
c.i_parents.Remove((Type)this);
i_children.Remove(c);
}
/// <summary>
/// Immediate parents only. Does not include this node
/// </summary>
public HashSet<Type> Parents { get { return i_parents; } }
/// <summary>
/// Immediate children only. Does not include this node
/// </summary>
public HashSet<Type> Children { get { return i_children; } }
/// <summary>
/// does not include this node
/// </summary>
public HashSet<Type> AllAncestors
{
get
{
HashSet<Type> l = AllAncestorsInclusive;
l.Remove((Type)this);
return l;
}
}
public HashSet<Type> AllAncestorsInclusive
{
get
{
HashSet<Type> l = new HashSet<Type>();
Action<Type> f = null;
f = (n) =>
{
foreach (Type t in n.i_parents)
if (!l.Contains(t))
f(t);
l.Add(n);
};
f((Type)this);
return l;
}
}
/// <summary>
/// does not include this node
/// </summary>
public HashSet<Type> AllDescendants
{
get
{
HashSet<Type> l = AllDescendantsInclusive;
l.Remove((Type)this);
return l;
}
}
public HashSet<Type> AllDescendantsInclusive
{
get
{
HashSet<Type> l = new HashSet<Type>();
Action<Type> f = null;
f = (n) =>
{
foreach (Type t in n.i_children)
if (!l.Contains(t))
f(t);
l.Add(n);
};
f((Type)this);
return l;
}
}
public void SetHasAnyFeaturesFlagBelow()
{
m_flags |= Flags.HasAnyFeatures;
foreach (Type c in this.i_children)
{
if ((c.m_flags & Flags.HasAnyFeatures) == 0)
c.SetHasAnyFeaturesFlagBelow();
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
/// Proper subtype relationship, ⊐, as in: t ⊐ *top*
/// Returns 'true' if this node is in the proper child graph of the specified argument.
/// Complementary to IsSupertypeOf.
/// This is used by the graph closure, so it does not use the GLB cache, and must not be made to do so.
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public bool IsSubtypeOf(Type tt_other)
{
return (tt_other == this) ? false : m_code.AndGivesExact(tt_other.m_code);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
/// Proper subsumption, ⊏, as in: top.Subsumes(everything-else).
/// Returns 'true' if this node is properly in the parent graph of the specified argument.
/// Complementary to IsSubtypeOf.
/// This is used by the graph closure, so it does not use the GLB cache, and must not be made to do so.
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public bool IsSupertypeOf(Type tt_other)
{
return (tt_other == this) ? false : tt_other.m_code.AndGivesExact(m_code);
}
};
}