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