using System; using System.Collections.Generic; using System.IO; using System.Runtime.Serialization.Formatters.Binary; using System.Threading; using System.Linq; using glue.Collections.BitArray; using glue.Tasks; #pragma warning disable 0162 namespace agree { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// /// /// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public partial class TypeMgr { public partial struct FeatureInfo { public FeatureInfo(BinaryReader br, Type[] type_arr) { this.i_feat = br.ReadInt32(); this.feature = br.ReadString(); this.maximal_type = type_arr[br.ReadUInt16()]; #if DEBUG this.AppropriateFor = new HashSet<Type>(); #endif } public void Write(BinaryWriter bw) { bw.Write(i_feat); bw.Write(feature); bw.Write(maximal_type.m_id); } }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// /// /// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public void Save(CommandToken tx, BinaryWriter bw) { // write types bw.Write(code_size); bw.Write(c_types); for (int i = 0; i < c_types; i++) type_arr[i].Write(bw, i); // write features bw.Write(feat_arr.Length); for (int i = 0; i < feat_arr.Length; i++) feat_arr[i].Write(bw); // write strings strings.Write(bw); // write trays Tray[] rgtr = TrayMgr.GetTypeMgrTrays(this).ToArray(); bw.Write(rgtr.Length); foreach (Tray _tr in rgtr) _tr.Write(bw); // write expanded TFSs for types for (int i = 0; i < c_types; i++) type_arr[i].WriteTfss(bw); // write entries bw.Write(entry_dict.Count); foreach (Entry ent in entry_dict.Values) ent.Write(bw); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// /// /// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public void LoadBinary(CommandToken tx, BinaryReader br) { // read types code_size = br.ReadInt32(); c_types = br.ReadInt32(); type_arr = new Type[c_types]; int[][] tdp = new int[c_types][]; int[][] tdc = new int[c_types][]; code_dict = new Dictionary<BitArr, Type>(); for (int i = 0; i < c_types; i++) { Type t = new Type(this, br, out tdp[i], out tdc[i]); type_dict[t.Name] = t; type_arr[i] = t; code_dict.Add(t.m_code, t); } for (int i = 0; i < c_types; i++) { Type t = type_arr[i]; int[] td; td = tdp[i]; if (td != null) foreach (int type_id in td) t.AddIParent(type_arr[type_id]); td = tdc[i]; if (td != null) foreach (int type_id in td) t.AddIChild(type_arr[type_id]); } tdp = tdc = null; // read features int c_feat = br.ReadInt32(); feat_arr = new FeatureInfo[c_feat]; for (int i = 0; i < c_feat; i++) { FeatureInfo fi = new FeatureInfo(br, type_arr); feat_arr[i] = fi; feat_map.Add(fi.feature, fi); } #if DEBUG foreach (Type t in type_arr) foreach (int i in t._deprec_feat_indexes) feat_arr[i].AppropriateFor.Add(t); #endif // read strings strings.Read(br); // load trays Dictionary<int, Tray> tray_map = new Dictionary<int, Tray>(); int c_tr = br.ReadInt32(); for (int i = 0; i < c_tr; i++) { var kvp = Tray.Load(this, br); tray_map.Add(kvp.Value, kvp.Key); } // read def/expand for types. They need to map tray indexes hence the delay in doing this. for (int i = 0; i < c_types; i++) type_arr[i].ReadTfss(br, tray_map); // read entries int c_ent = br.ReadInt32(); for (int i = 0; i < c_ent; i++) { Entry e = Entry.Read(br, this, tray_map); entry_dict.Add(e.Name, e); } /// Resolve special types: attach special configuration types used in lists, etc. ResolveSpecialTypes(); /// Resolve start symbols and some special rule types ResolveSpecialEntries(); } }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// /// /// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public partial class Strings { public void Write(BinaryWriter bw) { bw.Write(dict.Count); foreach (var kvp in dict.Enumerate()) { bw.Write(kvp.Key); bw.Write(kvp.Value); } } public void Read(BinaryReader br) { next_string_id = br.ReadInt32(); for (int i = 0; i < next_string_id; i++) dict.Add(br.ReadString(), br.ReadInt32()); } }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// /// /// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public abstract partial class Instance : ISysObj { protected static BinaryFormatter bf = new BinaryFormatter(); public Instance(TypeMgr tm, BinaryReader br) { this.mgr = tm; this.m_flags = (Flags)br.ReadInt32(); this.name = br.ReadString(); } public virtual void Write(BinaryWriter bw) { bw.Write((Int32)m_flags); bw.Write(name); } }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// /// /// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public abstract partial class Entry : Instance { protected Entry(Type t, BinaryReader br, Dictionary<int,Tray> tray_map) : base(t.mgr, br) { this.t = t; this._definition = TfsEdge.Read(br, tray_map); } public static Entry Read(BinaryReader br, TypeMgr tm, Dictionary<int, Tray> tray_map) { String s_type = br.ReadString(); int typeid = br.ReadInt32(); Type t = tm.type_arr[typeid]; Entry e; switch (s_type) { case "GrammarRule": e = new GrammarRule(t, br, tray_map); break; case "MorphologicalRule": e = new MorphologicalRule(t, br, tray_map); break; case "LexicalRule": e = new LexicalRule(t, br, tray_map); break; case "StartSymbol": e = new StartSymbol(t, br, tray_map); break; case "NodeLabelTemplate": e = new NodeLabelTemplate(t, br, tray_map); break; case "NodeMetaTemplate": e = new NodeMetaTemplate(t, br, tray_map); break; case "LexicalEntry": e = new LexicalEntry(t, br, tray_map); break; default: throw new Exception("unrecognized entry type: '" + s_type + "'"); } return e; } public override void Write(BinaryWriter bw) { // read by static function String s_type = this.GetType().Name; bw.Write(s_type); bw.Write(t.m_id); // read by base class constructor base.Write(bw); // read by this class constructor _definition.Write(bw); } }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public abstract partial class StaticExpandEntry : Entry { public StaticExpandEntry(Type t, BinaryReader br, Dictionary<int, Tray> tray_map) : base(t, br, tray_map) { if ((m_flags & Flags.Expanded) > 0) _expanded = TfsEdge.Read(br, tray_map); } public override void Write(BinaryWriter bw) { //if ((m_flags & Flags.Expanded) > 0) // _expanded.Write(bw); //base.Write(bw); } }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// /// /// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public abstract partial class DemandExpandEntry : Entry { public DemandExpandEntry(Type t, BinaryReader br, Dictionary<int, Tray> tray_map) : base(t, br, tray_map) { } }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// /// /// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public partial class LexicalEntry : DemandExpandEntry { public LexicalEntry(Type t, BinaryReader br, Dictionary<int, Tray> tray_map) : base(t, br, tray_map) { words = new String[br.ReadInt32()]; for (int i = 0; i < words.Length; i++) words[i] = br.ReadString(); } public override void Write(BinaryWriter bw) { base.Write(bw); bw.Write(words.Length); foreach (String s in words) bw.Write(s); } }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// /// /// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public partial class LexicalRule : Rule { public LexicalRule(Type t, BinaryReader br, Dictionary<int, Tray> tray_map) : base(t, br, tray_map) { } public override void Write(BinaryWriter bw) { base.Write(bw); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// /// /// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public partial class MorphologicalRule : LexicalRule { public MorphologicalRule(Type t, BinaryReader br, Dictionary<int, Tray> tray_map) : base(t, br, tray_map) { morph_subrules = (MorphologySubrule[])bf.Deserialize(br.BaseStream); if (morph_subrules.Length == 0) throw new Exception("a morphological rule with no subrules should be a lexical rule"); } public override void Write(BinaryWriter bw) { base.Write(bw); MorphologySubrule[] ms = morph_subrules ?? new MorphologySubrule[0]; bf.Serialize(bw.BaseStream, ms); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// /// /// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public abstract partial class GlbDag : Instance { public GlbDag(TypeMgr tm, BinaryReader br) : base(tm, br) { m_id = br.ReadUInt16(); m_level = br.ReadUInt16(); m_code = new BitArr(mgr.code_size, br); } public override void Write(BinaryWriter bw) { base.Write(bw); bw.Write(m_id); bw.Write(m_level); m_code.Write(bw); } }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// /// /// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public partial class Type : GlbDag { public Type(TypeMgr tm, BinaryReader br, out int[] parent_ids, out int[] child_ids) : base(tm, br) { int c; c = br.ReadInt32(); if (c == 0) parent_ids = null; else { parent_ids = new int[c]; for (int i = 0; i < c; i++) parent_ids[i] = br.ReadUInt16(); } c = br.ReadInt32(); if (c == 0) child_ids = null; else { child_ids = new int[c]; for (int i = 0; i < c; i++) child_ids[i] = br.ReadUInt16(); } c = br.ReadInt32(); if (c == 0) fc = FeatureConfig.Empty; else { var tmp = new int[c]; for (int i = 0; i < c; i++) tmp[i] = br.ReadInt32(); fc = tm.fcm.Get(tmp); } } public void Write(BinaryWriter bw, int id) { if (id != m_id) throw new Exception(); base.Write(bw); bw.Write(i_parents.Count); foreach (Type t in i_parents) bw.Write(t.m_id); bw.Write(i_children.Count); foreach (Type t in i_children) bw.Write(t.m_id); bw.Write(fc.Count); foreach (int i_feat in fc.rg_fix) bw.Write(i_feat); } public void WriteTfss(BinaryWriter bw) { if ((m_flags & Type.Flags.LoadedDefinition) > 0) Definition.Write(bw); if ((m_flags & Type.Flags.Expanded) > 0) Expanded.Write(bw); } public void ReadTfss(BinaryReader br, Dictionary<int, Tray> tray_map) { if ((m_flags & Type.Flags.LoadedDefinition) > 0) _definition = TfsEdge.Read(br, tray_map); if ((m_flags & Type.Flags.Expanded) > 0) _set_expanded(TfsEdge.Read(br, tray_map)); } }; public partial struct TfsEdge : IEquatable<TfsEdge>, ParseChart.IMotherDaughter { public void Write(BinaryWriter bw) { bw.Write(this.ttid); bw.Write((UInt64)Edge); } public static TfsEdge Read(BinaryReader br, Dictionary<int,Tray> tray_map) { int ttid = br.ReadInt32(); int tfs_id = ttid & unchecked((int)0xFFFFFFC0); int tix = ttid & 0x3F; return new TfsEdge(tfs_id | tray_map[tix].tix, (Edge)br.ReadUInt64()); } }; public abstract partial class Tray { public void Write(BinaryWriter bw) { // write old index, so that reader can map TFSs to a possibly new one bw.Write(tix); // write pools and tray info bw.Write(last_mark_issued); bw.Write(next_id); int c_pools = Pools.Length; bw.Write(c_pools); for (int i = 0; i < c_pools; i++) { ConstraintPool cp = Pools[i]; throw new Exception("won't work with lock free pool if count is disabled"); //int c_edges = cp.Count; //bw.Write(c_edges); //foreach (var pe in cp.PoolEdges) //{ // bw.Write(pe.Key); // bw.Write((UInt64)pe.Value); //} } } public static KeyValuePair<Tray,int> Load(TypeMgr tm, BinaryReader br) { int old_tix = br.ReadInt32(); // read pools and tray info int next_mark = br.ReadInt32(); int next_tfsid = br.ReadInt32(); Tray tray = TrayMgr.Allocate<ConcurrentTray>(tm,next_mark, next_tfsid); int c_pools = br.ReadInt32(); for (int i = 0; i < c_pools; i++) { ConstraintPool cp = tray.Pools[i]; int c_edges = br.ReadInt32(); for (int j = 0; j < c_edges; j++) cp.SetEdge(br.ReadInt32(), (Edge)br.ReadUInt64()); } return new KeyValuePair<Tray, int>(tray, old_tix); } }; }