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 class MarkingTfs : Tfs { public MarkingTfs(TypeMgr tm) : base(tm) { } public MarkingTfs(TypeMgr tm, Edge e) : base(tm, e) { } public MarkingTfs(TypeMgr tm, Type t, bool f_coref) : base(tm) { Edge = CreateEdge(t, f_coref); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Auto-mark based on the bareness of the type /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public Edge CreateEdge(Type t, bool f_coref) { Debug.Assert(t != null && t.tm == this.tm); Edge.Flag f; if (t == tm.StringType) f = Edge.Flag.EtmString; else { f = (Edge.Flag)t.m_id; if ((t.m_flags & Type.Flags.HasAnyFeatures) > 0) f |= Edge.Flag.EtmNonBareType; } if (f_coref) f |= Edge.Flag.Coreference; int m = (f & (Edge.Flag.Coreference | Edge.Flag.EtmNonBareType)) == 0 ? 0 : next_mark++; return new Edge(f, m); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Auto-mark based on the bareness of the type /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public Edge CreateEdge(Edge.Flag f) { Debug.Assert(tm.GetEdgeType(f).IsBare == ((f & Edge.Flag.EtmNonBareType) == 0)); return new Edge(f, (f & (Edge.Flag.Coreference | Edge.Flag.EtmNonBareType)) == 0 ? 0 : next_mark++); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Create an edge which will be used in this tray. The edge is not persisted into the tray. /// Caller may not submit a non-bare mark if the requirements for a non-bare mark are not met /// But caller can optionally submit a bare mark for any new edge; the current design enforces that non-bare /// types will always have a non-bare mark /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public Edge CreateRecycledEdge(Type t, int m, bool f_coref) { Debug.Assert(t != null && t.tm == this.tm); Edge.Flag f; if (t == tm.StringType) f = Edge.Flag.EtmString; else { f = (Edge.Flag)t.m_id; if ((t.m_flags & Type.Flags.HasAnyFeatures) > 0) f |= Edge.Flag.EtmNonBareType; } if (f_coref) f |= Edge.Flag.Coreference; if ((f & (Edge.Flag.Coreference | Edge.Flag.EtmNonBareType)) != 0) { if (m == 0) m = next_mark++; } else { /// Caller may not submit a non-bare mark if the requirements for a non-bare mark are not met Debug.Assert(m == 0); } return new Edge(f, m); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Create an edge with the specified type, coreference status, and mark. /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public Edge CreateRecycledEdge(Edge.Flag f, int m) { Debug.Assert(tm.GetEdgeType(f).IsBare == ((f & Edge.Flag.EtmNonBareType) == 0)); if ((f & (Edge.Flag.Coreference | Edge.Flag.EtmNonBareType)) != 0) { if (m == 0) m = next_mark++; } else { /// Caller may not submit a non-bare mark if the requirements for a non-bare mark are not met Debug.Assert(m == 0); } return new Edge(f, m); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public void ChangeEdgeCoreference(FeatMark fm, bool f_coref) { Debug.Assert(fm.m != 0); Edge e = GetEdge(fm.i_feat, fm.m); if (f_coref) { Debug.Assert(!e.IsCoreferenced); if (tm.IsTopId(e)) e = CreateEdge(tm.TopType, true); else e = CreateRecycledEdge(e.FlagsId | Edge.Flag.Coreference, e.Mark); SetEdge(fm.i_feat, fm.m, e); } else { Debug.Assert(e.IsCoreferenced); if (tm.IsTopId(e)) RemoveEdge(fm.i_feat, fm.m); else { Debug.Assert(tm.GetEdgeType(e.FlagsId).IsBare == ((e.FlagsId & Edge.Flag.EtmNonBareType) == 0)); SetEdge(fm.i_feat, fm.m, new Edge(e.FlagsId & ~Edge.Flag.Coreference, (e.FlagsId & Edge.Flag.EtmNonBareType) == 0 ? 0 : e.Mark)); } } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Create a string value edge for a unique string value /// </summary> /// <remarks> /// note: empty string is distinct from unconstrained string type /// s1 := *top* & [ X *top* ]. /// s2 := s1 & [ X "foo" ]. /// s3 := s1 & [ X "" ]. /// s4 := s2 & s3. /// </remarks> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public Edge CreateStringEdge(String s) { if (tm.IsPetrified) throw new Exception("Type hierarchy has already finished loading, cannot add more strings"); int sid = tm.strings.GetOrAdd(s); return new Edge(Edge.Flag.EtmString | (Edge.Flag)sid, 0); } }; }