using System; using System.Text; using System.Collections.Generic; using System.Diagnostics; using System.Linq; namespace agree { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// ConstraintRef is a value type. It consists of: /// - reference to a top-level TFS which provides access to edges /// - a current host edge, which consists of a 'hosting' Type (which may or may not be the same as the introducing type for the /// constraint pool's feature), and an in-mark that selects an onwards edge in that constraint pool. /// - a selected feature index, relative to the TypeMgr of the TFS /// /// This structure is therefore able to indicate a specific FEATURE-type pair within a TFS, while maintaining the /// critically-important ability to alter that type assignment, which is not available given only an Edge. /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public partial struct ConstraintRef { public static readonly ConstraintRef[] NoneBelow = new ConstraintRef[0]; public ConstraintRef(Tfs tfs, Edge host, int i_feat) { this.Host = host; this.i_feat = i_feat; this.tfs = tfs; } public ConstraintRef(Tfs host) { this.Host = host.Edge; this.tfs = host; this.i_feat = -1; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// [DebuggerBrowsable(DebuggerBrowsableState.Never)] public Tfs tfs; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// The hosting edge. For 'read' performance, the field itself is exposed, but do not 'write' this field; use /// SetHost() or SetHostType() instead. /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// [DebuggerBrowsable(DebuggerBrowsableState.Never)] public Edge Host; public void SetHostType(Type new_type) { if (HostType != new_type) { Host = ((MarkingTfs)tfs).CreateRecycledEdge(new_type, Host.Mark, Host.IsCoreferenced); if (!HostType.HasFeature(i_feat)) i_feat = -1; } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// The selected feature is determined by a non-null ConstraintPool /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// [DebuggerBrowsable(DebuggerBrowsableState.Never)] public int i_feat; [DebuggerBrowsable(DebuggerBrowsableState.Never)] public FeatureInfo FeatureInfo { get { return tfs.tm.feat_arr[i_feat]; } } [DebuggerBrowsable(DebuggerBrowsableState.Never)] public String Feature { get { return tfs.tm.feat_arr[i_feat].feature; } } [DebuggerBrowsable(DebuggerBrowsableState.Never)] public Type HostType { get { return tfs.tm.GetEdgeType(Host.FlagsId); } } [DebuggerBrowsable(DebuggerBrowsableState.Never)] public FeatMark FeatMark { get { return new FeatMark(i_feat, Host.Mark); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Stays in the same Tray /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public void SwitchToFeature(int i_feat) { if (this.i_feat==-1 || this.i_feat != i_feat) { if (i_feat == -1 || !HostType.HasFeature(i_feat)) throw new Exception(); this.i_feat = i_feat; } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /// <remarks> /// value type semantics are weird for 'set' as a property so we use a method instead /// </remarks> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// [DebuggerBrowsable(DebuggerBrowsableState.Never)] public Edge Constraint { get { return tfs.GetEdge(i_feat, Host.Mark); } } public void SetConstraint(Edge e) { tfs.SetEdge(i_feat, Host.Mark, e); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// [DebuggerBrowsable(DebuggerBrowsableState.Never)] public Type ConstraintType { get { Edge e; if (!tfs.TryGetEdge(i_feat, Host.Mark, out e)) return tfs.tm.TopType; return tfs.tm.GetEdgeType(e.FlagsId); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// returns 'true' even if coreferenced /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// [DebuggerBrowsable(DebuggerBrowsableState.Never)] public bool ConstraintTypeIsTop { get { return ConstraintType.IsTop; } } [DebuggerBrowsable(DebuggerBrowsableState.Never)] public bool ConstraintTypeIsBare { get { return ConstraintType.IsBare; } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// always stays in the same TFS /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public ConstraintRef NextConstraint(int i_nf) { return new ConstraintRef(tfs, tfs.GetEdge(this.i_feat, Host.Mark), i_nf); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Unify types, only used by TdlNavigator /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public bool UnifyInConstraintType(Type t) { Debug.Assert(i_feat != -1, "UnifyInType: Edge has no feature selected."); int tid = ConstraintType.m_id; int glb_id = t.tm.GetGlbCheckTopAndIdentity(tid, t.m_id); if (glb_id == -1) return false; if (glb_id != tid) { Edge old_edge = tfs.GetEdge(i_feat, Host.Mark); tfs.SetEdge(i_feat, Host.Mark, ((MarkingTfs)tfs).CreateRecycledEdge(t.tm.type_arr[glb_id], old_edge.Mark, old_edge.IsCoreferenced)); } return true; } }; }