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; } }; }