using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using miew.Debugging;
using miew.Enumerable;
using miew.String;
namespace agree
{
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
///
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public abstract partial class Tfs : ISysObj
{
///this was DEBUG code... generally do not use
public bool GetEdgeAtPath(Edge e_start, FsPath p, out Edge e)
{
e = e_start;
foreach (String f in p)
{
int i_feat = tm.GetFeatureIndex(f);
if (i_feat == -1 || !TryGetEdge(i_feat, e.Mark, out e))
return false;
}
return true;
}
public Edge GetEdgeAtPath(String p)
{
Edge e;
GetEdgeAtPath(Edge, new FsPath(p), out e);
return e;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
///
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public bool GetEdgeAtPath(Edge e_start, FsPath p, out ConstraintRef cref)
{
if (p.Count == 0)
{
cref = default(ConstraintRef);
return false;
}
Edge e = e_start;
Edge e_prev;
for (int i = 0; ; )
{
e_prev = e;
int i_feat = tm.GetFeatureIndex(p[i]);
if (i_feat == -1 || !TryGetEdge(i_feat, e.Mark, out e))
{
cref = default(ConstraintRef);
return false;
}
i++;
if (i == p.Count)
{
cref = new ConstraintRef(this, e_prev, i_feat);
return true;
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
///
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public IEnumerable<Edge> GetListEdges(Edge e)
{
/// e.Type must unify down to tt_list_parent, but we don't need to check this separately because the ListHead pool
/// is only appropriate for types that are lists, so the Mark won't be found if e.Type is not a list.
Edge lh_edge;
while (TryGetEdge(tm.f_ix_list_head, e.Mark, out lh_edge))
{
yield return lh_edge;
if (!TryGetEdge(tm.f_ix_list_tail, e.Mark, out e) || e.Mark == 0)
yield break;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
///
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public IEnumerable<PathEdge> GetListPathEdges(Edge e)
{
/// e.Type must unify down to tt_list_parent, but we don't need to check this separately because the ListHead pool
/// is only appropriate for types that are lists, so the Mark won't be found if e.Type is not a list.
Edge lh_edge;
List<int> fix_path = new List<int>(4);
while (TryGetEdge(tm.f_ix_list_head, e.Mark, out lh_edge))
{
fix_path.Add(tm.f_ix_list_head);
yield return new PathEdge(fix_path, lh_edge);
fix_path[fix_path.Count - 1] = tm.f_ix_list_tail;
if (!TryGetEdge(tm.f_ix_list_tail, e.Mark, out e) || e.Mark == 0)
yield break;
}
}
#if false
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
///
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public IEnumerable<TfsSection> GetSectionsFromPathToList(TypeMgrCompiledFsPath p)
{
List<ConstraintRef> path_to_list = p.WalkPath(this).ToList();
foreach (Edge e in GetListEdges(path_to_list[path_to_list.Count - 1].Constraint))
{
TfsSection ts = new TfsSection(this, e);
yield return ts;
}
}
#endif
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
///
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public IEnumerable<ConstraintRef> GetListConstraintRefs(Edge e)
{
Edge lh_edge;
while (TryGetEdge(tm.f_ix_list_head, e.Mark, out lh_edge))
{
yield return new ConstraintRef(this, e, tm.f_ix_list_head);
if (!TryGetEdge(tm.f_ix_list_tail, e.Mark, out e))
yield break;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
///
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public IEnumerable<ConstraintRef> GetDiffListLists(Edge e)
{
Edge ll_edge;
if (!TryGetEdge(tm.f_ix_dlist_list, e.Mark, out ll_edge))
yield break;
foreach (ConstraintRef cr in GetListConstraintRefs(ll_edge))
yield return cr;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
///
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public IEnumerable<FeatMark> AllFeatMarks(Edge e)
{
return e.Mark != 0 ?
tm.rgrgfix_by_type[(int)(e.FlagsId & Edge.Flag.MultiIdMask)].Select(fix => new FeatMark(fix, e.Mark)) :
Enumerable.Empty<FeatMark>();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
///
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public IEnumerable<int> AllPools
{
get
{
Debug.Assert(Edge.Mark != 0);
return tm.rgrgfix_by_type[(int)(Edge.FlagsId & Edge.Flag.MultiIdMask)];
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
///
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public IEnumerable<int> ConstrainedPoolsOnly()
{
Debug.Assert(Edge.Mark != 0);
int m = Edge.Mark;
if (m != 0)
{
foreach (int i_feat in tm.rgrgfix_by_type[(int)(Edge.FlagsId & Edge.Flag.MultiIdMask)])
if (ContainsFeatMark(i_feat, m))
yield return i_feat;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
///
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public IEnumerable<int> ConstrainedPoolsOnly(Edge e)
{
if (e.Mark != 0)
foreach (int i_feat in tm.rgrgfix_by_type[(int)(e.FlagsId & Edge.Flag.MultiIdMask)])
if (ContainsFeatMark(i_feat, e.Mark))
yield return i_feat;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
///
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public IEnumerable<ConstraintRef> AllConstraintRefs(Edge e)
{
if (e.Mark != 0)
foreach (int i_feat in tm.rgrgfix_by_type[(int)(e.FlagsId & Edge.Flag.MultiIdMask)])
yield return new ConstraintRef(this, e, i_feat);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
///
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public IEnumerable<ConstraintRef> ConstrainedRefsOnly(Edge e)
{
if (e.Mark != 0)
foreach (int i_feat in tm.rgrgfix_by_type[(int)(e.FlagsId & Edge.Flag.MultiIdMask)])
if (ContainsFeatMark(i_feat, e.Mark))
yield return new ConstraintRef(this, e, i_feat);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// <summary>
/// Includes coreferences, of course
/// Constrained means it is has at least one non-top or coreferenced feature. We count on the fact that such edges are
/// always vacant from the constraint pool
/// </summary>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public int ConstrainedFeaturesCount(Edge e)
{
int c = 0;
if (e.Mark != 0)
foreach (int i_feat in tm.rgrgfix_by_type[(int)(e.FlagsId & Edge.Flag.MultiIdMask)])
if (ContainsFeatMark(i_feat, e.Mark))
c++;
return c;
}
};
}