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