using System; using System.Collections.Generic; using System.Diagnostics; using System.Threading; using System.Text; using System.Linq; using glue.Collections.XSpinLock; using glue.Extensions.Enumerable; namespace agree { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public partial struct TfsEdge : IEquatable<TfsEdge>, ParseChart.IMotherDaughter, ISysObj { public readonly static IList<TfsEdge> rg_tfsedge_empty = new TfsEdge[0]; public static TfsEdge TargetTfsEdge = new TfsEdge(Tray.TargetId, default(Edge)); public TfsEdge(int ttid, Edge edge) { this.ttid = ttid; this.Edge = edge; } [DebuggerBrowsable(DebuggerBrowsableState.Never)] public int ttid; public Edge Edge; [DebuggerBrowsable(DebuggerBrowsableState.Never)] public bool IsTarget { get { return (ttid & 0xFFFFFFC0) == Tray.TargetId; } } [DebuggerBrowsable(DebuggerBrowsableState.Never)] public Tray Tray { get { return TrayMgr.all_trays[ttid & 0x3F]; } } [DebuggerBrowsable(DebuggerBrowsableState.Never)] public int TfsId { get { return ttid >> 6; } } [DebuggerBrowsable(DebuggerBrowsableState.Never)] public bool IsNull { get { return ttid == default(int); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public bool AtomicallySetToNull() { return Interlocked.CompareExchange(ref ttid, default(int), ttid) == ttid; } public bool PseudoAtomicStoreTo(ref TfsEdge dest) { int obs = dest.ttid; if (Interlocked.CompareExchange(ref dest.ttid, this.ttid, obs) != obs) return false; dest.Edge = this.Edge; return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public Type Type { get { TypeMgr tm = TrayMgr.all_trays[ttid & 0x3F].tm; return (Edge.FlagsId & Edge.Flag.EtmMask) == agree.Edge.Flag.EtmString ? tm.StringType : tm.type_arr[(int)(Edge.FlagsId & tm.MultiIdMask)]; } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public TfsEdge WrapEdgeInSameTfs(Edge e) { return new TfsEdge(this.ttid, e); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Create a copy of this TFS which will be treated as distinct if incorporated as some sub-part of a parent TFS /// multiple times during TFS expansion. /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public TfsEdge Clone() { return TrayMgr.all_trays[ttid & 0x3F].CloneTfs(this); } public String ToPathList(String label) { return TrayMgr.all_trays[ttid & 0x3F].ToPathList(Edge, label); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// [DebuggerBrowsable(DebuggerBrowsableState.Never)] public HashSet<PoolMark> PoolMarksBelow { get { return TrayMgr.all_trays[ttid & 0x3F].PoolMarksBelow(Edge); } } [DebuggerBrowsable(DebuggerBrowsableState.Never)] public IDictionary<Edge, CorefFinder.Entry> Coreferences { get { return TrayMgr.all_trays[ttid & 0x3F].GetCoreferences(Edge); } } [DebuggerBrowsable(DebuggerBrowsableState.Never)] public IEnumerable<ConstraintPool> ConstrainedPoolsOnly { get { int m = Edge.Mark; if (m == 0) yield break; Tray tr = TrayMgr.all_trays[ttid & 0x3F]; ConstraintPool[] rgcp = tr.Pools; foreach (int fix in tr.tm.GetEdgeType((Edge.Flag)Edge.FlagsId)._deprec_feat_indexes) { ConstraintPool cp = rgcp[fix]; if (cp.ContainsInMark(m)) yield return cp; } } } [DebuggerBrowsable(DebuggerBrowsableState.Never)] public IEnumerable<ConstraintPool> AllPools { get { Tray tr = TrayMgr.all_trays[ttid & 0x3F]; ConstraintPool[] rgcp = tr.Pools; foreach (int fix in tr.tm.GetEdgeType((Edge.Flag)Edge.FlagsId)._deprec_feat_indexes) yield return rgcp[fix]; } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public void RegisterName(String s) { Tray.RegisterTfsName(this, s); } [DebuggerBrowsable(DebuggerBrowsableState.Never)] public String Name { get { #if DEBUG int tfsid = TfsId; String s_tfsid = tfsid == 2 ? "T" : tfsid.ToString("X"); return String.Format("{0:X}:{1} {2}", ttid & 0x3F, s_tfsid, Edge);//Type.Name); #else return Tray.GetTfsName(this) ?? (ttid & 0x3F).ToString("X") + ":" + TfsId.ToString("X"); #endif } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public bool Equals(TfsEdge other) { return Edge.Mark == other.Edge.Mark && Edge.FlagsId == other.Edge.FlagsId && ttid == other.ttid; } public static bool operator ==(TfsEdge x, TfsEdge y) { throw new NotImplementedException(); } public static bool operator !=(TfsEdge x, TfsEdge y) { throw new NotImplementedException(); } public override bool Equals(object obj) { return obj is TfsEdge && Edge.Mark == ((TfsEdge)obj).Edge.Mark && Edge.FlagsId == ((TfsEdge)obj).Edge.FlagsId && ttid == ((TfsEdge)obj).ttid; } public override int GetHashCode() { return Edge.Mark + (int)Edge.FlagsId + (int)ttid; } public override string ToString() { return Name; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// ParseChart.IMotherDaughter /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// [DebuggerBrowsable(DebuggerBrowsableState.Never)] public IEnumerable<TfsEdge> RuleDaughters { get { Edge e; Tray tr = TrayMgr.all_trays[ttid & 0x3F]; if (!tr.RuleArgsPath.GetEdge(this.Edge.Mark, out e)) yield break; foreach (Edge x in tr.GetListEdges(e)) yield return WrapEdgeInSameTfs(x); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// ParseChart.IMotherDaughter /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public bool SpinCompare(TfsEdge other) { return this.Type == other.Type; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// ParseChart.IMotherDaughter /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// [DebuggerBrowsable(DebuggerBrowsableState.Never)] public TfsEdge Contents { get { return this; } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// IDisposable(ParseChart.IMotherDaughter) /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public void Dispose() { TrayMgr.all_trays[ttid & 0x3F].ReleaseTfs(this); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// TfsCoref manages a dictionary of coreferenced edges. The dictionary uses this special comparer so that dictionary /// operations only consider the TFS id and the out mark, and not the type or coreference status of the edge. /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public class TfsMarkComparer : IEqualityComparer<TfsEdge> { static public TfsMarkComparer Instance = new TfsMarkComparer(); public bool Equals(TfsEdge x, TfsEdge y) { return x.ttid == y.ttid && x.Edge.Mark == y.Edge.Mark; } public int GetHashCode(TfsEdge obj) { return (int)obj.ttid + obj.Edge.Mark; } }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// ISysObj.SysObjName /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// [DebuggerBrowsable(DebuggerBrowsableState.Never)] public string SysObjName { get { return ToString(); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// ISysObj.SysObjDescription /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// [DebuggerBrowsable(DebuggerBrowsableState.Never)] public string SysObjDescription { get { return ToString(); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// ISysObj.SysObjChildren /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// [DebuggerBrowsable(DebuggerBrowsableState.Never)] public glue.Collections.ReadOnly.IReadOnlyDictionary<string, ISysObj> SysObjChildren { get { return SysObjHelper<ISysObj>.Empty; } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// ISysObj.SysObjParent /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// [DebuggerBrowsable(DebuggerBrowsableState.Never)] public ISysObj SysObjParent { get { return Tray.tm.g; } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// static readonly EdgeCount[] rg_ec_empty = new EdgeCount[0]; public EdgeCount[] GetCorefCounts() { if ((Edge.FlagsId & Edge.Flag.EtmNonBareType) == 0) return rg_ec_empty; return new CorefFinder(TrayMgr.all_trays[ttid & 0x3F], Edge) .Result .Select(kvp => new EdgeCount(kvp.Key, kvp.Value.Count)) .ToArray(); } }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public partial struct EdgeCount { public EdgeCount(Edge e, int count) { this.edge = e; this.count = count; } public Edge edge; public int count; }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public partial class Tfs { public Tfs(TfsEdge te, EdgeCount[] corefs) { this.te = te; this.corefs = corefs; } public Tfs(TfsEdge te) { this.te = te; this.corefs = te.GetCorefCounts(); } public TfsEdge te; public EdgeCount[] corefs; public int CorefCount { get { return corefs.Length; } } }; }