using System; using System.Collections.Generic; using System.Diagnostics; using System.Threading; using miew.Debugging; namespace agree { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public sealed class TfsSection : Tfs { readonly public Tfs mother; int c_edges = -1; public int i_sect = -1; public TfsSection(Tfs mother, Edge daughter, int i_sect) : base(mother.tm, daughter) { this.mother = mother; this.i_sect = i_sect; this.next_mark = mother.next_mark; this.next_coref_mark = mother.next_coref_mark; //_load_coref_tally_map(false); } public TfsSection(Tfs mother, PathEdge pe, int i_sect) : this(mother, pe.e, i_sect) { } int ix_mother = -1; public int MotherSlotIndex { get { if (ix_mother == -1) { if (i_sect < 0 || i_sect > 1) throw new Exception(); int m = mother.GetEdgeAtPath(i_sect == 0 ? "args" : "args.rest").Mark; ix_mother = ((MotherDaughterTfs)mother).GetEdgeIndex(tm.f_ix_list_head, ref m); } return ix_mother; } } public void _load_coref_tally_map() { byte[] _tmp = null; int c_corefs = 0; int max_c = mother.coref_tally_map.Length; if (max_c > 0 && (this.Edge.FlagsId & Edge.Flag.EtmNonBareType) != 0) { _tmp = new byte[max_c]; EdgeCounter ec = new EdgeCounter(mother, this.Edge, _tmp); c_corefs = ec.ActualCount; c_edges = ec.EdgeCount; } if (c_corefs == 0 || _tmp == null) { _tmp = NoCorefsTallyMap; } coref_tally_map = _tmp; } public void _load_coref_tally_map_restricted() { byte[] _tmp = null; int c_corefs = 0; int max_c = mother.coref_tally_map.Length; if (max_c > 0 && (this.Edge.FlagsId & Edge.Flag.EtmNonBareType) != 0) { _tmp = new byte[max_c]; EdgeCounterRestricted ec = new EdgeCounterRestricted(mother, this.Edge, _tmp); c_corefs = ec.ActualCount; c_edges = ec.EdgeCount; } if (c_corefs == 0 || _tmp == null) { _tmp = NoCorefsTallyMap; } coref_tally_map_restricted = _tmp; } public TfsEdge SectionTfsEdge { get { return new TfsEdge(mother, Edge); } } public bool IsSectionOf(Tfs putative) { return putative == mother; } public Tfs MotherTfs { get { return mother; } } public override void SetEdge(int i_feat, int mark, Edge e) { mother.SetEdge(i_feat, mark, e); } public override bool TryGetEdge(int i_feat, int mark, out Edge e) { return mother.TryGetEdge(i_feat, mark, out e); } public override Edge.Flag TryGetFlagsMark(int i_feat, int mark, out int m) { return mother.TryGetFlagsMark(i_feat, mark, out m); } public override ulong GetUlEdge(FeatMark fm) { return mother.GetUlEdge(fm); } public override bool RemoveEdge(int i_feat, int mark) { return mother.RemoveEdge(i_feat, mark); } public override void AddEdge(int i_feat, int mark, Edge e) { mother.AddEdge(i_feat, mark, e); } public override Edge GetEdge(int i_feat, int mark) { return mother.GetEdge(i_feat, mark); } public override IEnumerable<FeatMarkEdge> FeatMarkEdges { get { return new FeatMarkEdgeGatherer(mother).Gather(this.Edge); } } public override bool ContainsFeatMark(int i_feat, int mark) { /// not the correct result for the TFS section Nop.CodeCoverage(); return mother.ContainsFeatMark(i_feat, mark); } public override bool _ContainsInMark(int mark) { /// not the correct result for the TFS section Nop.CodeCoverage(); return mother._ContainsInMark(mark); } public override int EdgeCount { get { if (c_edges != -1) return c_edges; /// not the correct result for the TFS section Nop.CodeCoverage(); return mother.EdgeCount; } } public override Tfs Clone() { throw new NotImplementedException(); } }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public sealed class TinyTfs : Tfs { readonly public FeatMarkEdge[] entries; unsafe public TinyTfs(TypeMgr tm, Edge root, IDictionary<ulong, Edge> d, TargetTfs tt) : base(tm, root) { int c = d.Count; Debug.Assert(c > 0); this.entries = new FeatMarkEdge[c]; fixed (FeatMarkEdge* _base = &entries[0]) { FeatMarkEdge* pfme = _base; foreach (var kvp in d) { pfme->i_feat = (int)(kvp.Key >> 32); pfme->mark = (int)kvp.Key; pfme->e = kvp.Value; if (tt != null && pfme->e.FlagsId < 0) { Unification.UnifCoref uc = tt.corefs[((long)tt.id << 32) | (uint)pfme->e.Mark]; while (uc.f_redirect) uc = uc.next; pfme->e = uc.e_cur; } pfme++; } int c_corefs = 0; Debug.Assert(next_coref_mark == -1); for (int i = 0; i < c; i++) { int m_old = _base[i].e.Mark; if (_base[i].e.FlagsId < 0 && m_old > 0) { int m_new = next_coref_mark--; c_corefs++; pfme = _base; for (int j = 0; j < c; j++) { if (pfme->mark == m_old) pfme->mark = m_new; if (pfme->e.Mark == m_old) pfme->e = new Edge(pfme->e.FlagsId, m_new); pfme++; } } } if (c_corefs == 0) coref_tally_map = Tfs.NoCorefsTallyMap; else { coref_tally_map = new byte[c_corefs]; pfme = _base; for (int i = 0; i < c; i++) { int m = pfme->e.Mark; if (pfme->e.Mark < 0) coref_tally_map[~m]++; } } } Array.Sort<FeatMarkEdge>(this.entries); } public TinyTfs(BootstrapTfs dtfs) : this(dtfs.tm, dtfs.Edge, dtfs.d, null) { } public TinyTfs(TargetTfs tt) : this(tt.tm, tt.Edge, tt.d, tt) { } public TinyTfs(TinyTfs to_clone) : base(to_clone.tm, to_clone.Edge) { this.entries = to_clone.entries; this.coref_tally_map = to_clone.coref_tally_map; } public unsafe override bool TryGetEdge(int i_feat, int mark, out Edge e) { fixed (FeatMarkEdge* _base = entries) { FeatMarkEdge* pe = _base; FeatMarkEdge* end = _base + entries.Length; int d; do { d = pe->mark - mark; if (d == 0) d = pe->i_feat - i_feat; if (d == 0) { e = pe->e; return true; } } while (d < 0 && ++pe < end); } e = default(Edge); return false; } public unsafe override Edge.Flag TryGetFlagsMark(int i_feat, int mark, out int m) { fixed (FeatMarkEdge* _base = entries) { FeatMarkEdge* pe = _base; FeatMarkEdge* end = _base + entries.Length; int d; do { d = pe->mark - mark; if (d == 0) d = pe->i_feat - i_feat; if (d == 0) { m = pe->e.Mark; return pe->e.FlagsId; } } while (d < 0 && ++pe < end); } m = 0; return 0; } public unsafe override ulong GetUlEdge(FeatMark fm) { fixed (FeatMarkEdge* _base = entries) { FeatMarkEdge* pe = _base; FeatMarkEdge* end = _base + entries.Length; int d; do { d = pe->mark - fm.m; if (d == 0) d = pe->i_feat - fm.i_feat; if (d == 0) return *(ulong*)&pe->e; } while (d < 0 && ++pe < end); } return 0; } public override Edge GetEdge(int i_feat, int mark) { int d, i = 0; do { d = entries[i].mark - mark; if (d == 0) d = entries[i].i_feat - i_feat; if (d == 0) return entries[i].e; } while (d < 0 && ++i < entries.Length); return default(Edge); } public override IEnumerable<FeatMarkEdge> FeatMarkEdges { get { return entries; } } public override bool ContainsFeatMark(int i_feat, int mark) { int d, i = 0; do { d = entries[i].mark - mark; if (d == 0) d = entries[i].i_feat - i_feat; if (d == 0) return true; } while (d < 0 && ++i < entries.Length); return false; } public override bool _ContainsInMark(int mark) { for (int i = 0; i < entries.Length; i++) if (entries[i].mark == mark) return true; return false; } public override int EdgeCount { get { return entries.Length; } } public override void SetEdge(int i_feat, int mark, Edge e) { throw new InvalidOperationException(); } public override bool RemoveEdge(int i_feat, int mark) { throw new InvalidOperationException(); } public override void AddEdge(int i_feat, int mark, Edge e) { throw new InvalidOperationException(); } public override Tfs Clone() { return coref_tally_map.Length == 0 ? this : new TinyTfs(this); } }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public sealed class BareTfs : Tfs { public BareTfs(Type t) : base(t.tm, t.tm.CreateEdge(t, t.IsBare ? 0 : 1, false)) { coref_tally_map = NoCorefsTallyMap; } public override bool TryGetEdge(int i_feat, int mark, out Edge e) { e = default(Edge); return false; } public override Edge.Flag TryGetFlagsMark(int i_feat, int mark, out int m) { m = 0; return 0; } public override ulong GetUlEdge(FeatMark fm) { return 0; } public override Edge GetEdge(int i_feat, int mark) { return default(Edge); } public override bool ContainsFeatMark(int i_feat, int mark) { return false; } public override void SetEdge(int i_feat, int mark, Edge e) { throw new InvalidOperationException(); } public override bool RemoveEdge(int i_feat, int mark) { throw new InvalidOperationException(); } public override void AddEdge(int i_feat, int mark, Edge e) { throw new InvalidOperationException(); } public override IEnumerable<FeatMarkEdge> FeatMarkEdges { get { yield break; } } public override bool _ContainsInMark(int mark) { return false; } public override int EdgeCount { get { return 0; } } public override int ScratchAlloc { get { return 0; } } public override Tfs Clone() { return this; } }; [DebuggerDisplay("{fc.ToString(),nq}")] public class FeatureSlotTfs : Tfs { const int TopmostMark = 1; public FeatureSlotTfs(TypeMgr tm, Type for_example) : base(tm, tm.CreateEdge(for_example ?? tm.TopType, TopmostMark, false)) { this.next_mark = 2; } public FeatureSlotTfs(FeatureConfig fc, Type for_example) : this(fc.TypeMgr, for_example) { this.fc = fc; this.Name = "max feat config for " + fc.ToString(); } readonly FeatureConfig fc; //public override bool GetEdgeIndex(int i_feat, int mark, out int mix, out Edge e) //{ // Debug.Assert(mark == TopmostMark); // mix = (i_feat % fc.modulus) + 1; // e = default(Edge); // return true; //} //public override FeatMark GetSlotFeatMark(int mix) //{ // Debug.Assert(mix > 0); // mix--; // Debug.Assert(mix < fc.modulus); // foreach (int fix in fc) // if (mix == fix % fc.modulus) // return new FeatMark(fix, TopmostMark); // return default(FeatMark); //} public override bool TryGetEdge(int i_feat, int mark, out Edge e) { Debug.Assert(mark == TopmostMark); e = default(Edge); return true; } public override Edge.Flag TryGetFlagsMark(int i_feat, int mark, out int m) { Debug.Assert(mark == TopmostMark); m = 0; return 0; } public override ulong GetUlEdge(FeatMark fm) { Debug.Assert(fm.m == TopmostMark); return 0; } public override Edge GetEdge(int i_feat, int mark) { Debug.Assert(mark == TopmostMark); return default(Edge); } public override int EdgeCount { get { return fc.Count; } } public override int ScratchAlloc { get { return fc.modulus; } } public override void SetEdge(int i_feat, int mark, Edge e) { throw new InvalidOperationException(); } public override bool RemoveEdge(int i_feat, int mark) { throw new InvalidOperationException(); } public override void AddEdge(int i_feat, int mark, Edge e) { throw new InvalidOperationException(); } public override IEnumerable<FeatMarkEdge> FeatMarkEdges { get { foreach (int fix in fc) yield return new FeatMarkEdge(fix, TopmostMark, default(Edge)); } } public override bool ContainsFeatMark(int i_feat, int mark) { return mark == TopmostMark && fc.Contains(i_feat); } public override bool _ContainsInMark(int mark) { return mark == TopmostMark; } public override Tfs Clone() { throw new NotImplementedException(); } }; }