using System; using System.Collections.Generic; using System.Diagnostics; using glue.Collections.ReadOnly; namespace agree { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// In accordance with DELPH-IN tradition, we distinguish "types" from "entries." (Copestake 2002 p.106) /// Entries include everything except Types: lexical entries, grammar rules, start symbols, and node labels. /// In common, both share this abstract base class, Instance, which captures the idea of something that can /// have constraints. Types participate in a DAG hierarchy whereas Entries instead refer to a single Type. Thus, /// while Types and Entries have an is-a (inheritance) relationship with Instance, every Entry additionally has /// a has-a (contains) relationship with exactly one Type. /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public abstract partial class Instance : ISysObj { public Instance(TypeMgr mgr, String name, List<BaseFeatConstraint> bfc) { this.mgr = mgr; this.name = name; SetConstraints(bfc); } /// <summary> /// Type manager (TypeMgr) that this type belongs to /// </summary> public readonly TypeMgr mgr; public Flags m_flags; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// [DebuggerBrowsable(DebuggerBrowsableState.Never)] readonly protected String name; public String Name { get { return name; } } public String SysObjName { get { return name; } } public string SysObjDescription { get { return name; } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// [Flags] public enum Flags { /// <summary>set for a type with no child types</summary> Leaf = 0x00000001, /// <summary>set if this type is a system-generated greater lowest bound (glb) type</summary> GlbType = 0x00000002, /// <summary>set if this type has any appropriate (inherited or local) features</summary> HasAnyFeatures = 0x00000004, /// <summary></summary> HasLocalFeatures = 0x00000008, /// <summary>set if there are no appropriate features in this type's subgraph (inclusive)</summary> Atomic = 0x00000010, /// <summary>useful for skipping well-formedness unification when a ⊓ b ⊏ glb</summary> HasConstraints = 0x00000020, Bottom = 0x00000040, /// <summary>set when the type's inherited features have been computed</summary> LoadedNonLocalFeatures = 0x00010000, /// <summary>set when the type's authored constraint has been constructed based on its TDL tokens</summary> LoadedDefinition = 0x00020000, /// <summary>set when the type has been unified with its own constraint and with its parent types</summary> //Expanding = 0x00040000, Expanded = 0x00080000, }; /// <summary> /// if a type has no appropriate features, it can be structure-shared /// </summary> public bool HasAnyFeatures { get { return (m_flags & Flags.HasAnyFeatures) > 0; } } public bool IsBare { get { return (m_flags & Flags.HasAnyFeatures) == 0; } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public List<BaseFeatConstraint> m_bfc; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public void SetConstraints(List<BaseFeatConstraint> bfc) { if (bfc != null) { if (m_bfc == null) m_bfc = bfc; else m_bfc.AddRange(bfc); m_flags |= Type.Flags.HasConstraints; } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// [DebuggerDisplay("{m_flags.HasFlag(Flags.LoadedDefinition)?_definition.ToString():\"(definition not loaded yet)\",nq}")] protected TfsEdge _definition; [DebuggerBrowsable(DebuggerBrowsableState.Never)] // side effects public TfsEdge Definition { get { if ((m_flags & Flags.LoadedDefinition) == 0) throw new Exception("Definition not loaded yet."); return _definition; } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// internal void LoadDefinition(Tray tr) { if ((m_flags & Flags.LoadedDefinition) > 0) return; Type t = InstanceType; _definition = tr.CreateTfs(t, false); if (!IsBare && m_bfc != null) { ConstraintRef cref = new ConstraintRef(_definition); using (TdlNavigator bn = new TdlNavigator(tr, t)) { foreach (BaseFeatConstraint bfc in m_bfc) bn.AcceptBaseConstraint(cref, bfc); } m_bfc = null; } m_flags |= Flags.LoadedDefinition; } public abstract Type InstanceType { get; } [DebuggerBrowsable(DebuggerBrowsableState.Never)] public abstract TfsEdge Expanded { get; } public IReadOnlyDictionary<String, ISysObj> SysObjChildren { get { return SysObjHelper<ISysObj>.Empty; } } public ISysObj SysObjParent { get { return mgr.g; } } }; }