Skip to content
Snippets Groups Projects
SOMDocs.cs 29.4 KiB
Newer Older
  • Learn to ignore specific revisions
  • using JsonSubTypes;
    using Newtonsoft.Json;
    using System.Collections.Generic;
    using System.Linq.Expressions;
    using System.Linq;
    using System;
    using UnityEngine;
    using MoreLinq;
    
    namespace REST_JSON_API
    {
    
    MaZiFAU's avatar
    MaZiFAU committed
        public class ApproximationComparer : EqualityComparer<object>
        {
            public static readonly ApproximationComparer Instance = new();
    
            public override bool Equals(object x, object y)
            {
                if (x.Equals(y))
                    return true;
                if (x.GetType() != y.GetType())
                    return false;
    
                if (x is float fx)
                    return Mathf.Approximately(fx, (float)y);
                if (x is Vector3 vx)
                    return Math3d.IsApproximatelyEqual(vx, (Vector3)y);
    
                return false;
            }
    
            public override int GetHashCode(object obj)
            {
                if (obj is float)
                    return typeof(float).GetHashCode();
                if (obj is Vector3)
                    return typeof(Vector3).GetHashCode();
    
                return obj.GetHashCode();
            }
        }
    
    
        [JsonConverter(typeof(JsonSubtypes), "kind")]
    
    MaZiFAU's avatar
    MaZiFAU committed
        [JsonSubtypes.KnownSubType(typeof(RAW), "RAW")]
    
        [JsonSubtypes.KnownSubType(typeof(OMS), "OMS")]
    
    MaZiFAU's avatar
    MaZiFAU committed
        [JsonSubtypes.KnownSubType(typeof(OMA), "OMA")]
    
        [JsonSubtypes.KnownSubType(typeof(OMV), "VAR")]
    
    MaZiFAU's avatar
    MaZiFAU committed
        [JsonSubtypes.KnownSubType(typeof(OML_Member), "OML")]
    
        [JsonSubtypes.KnownSubType(typeof(FUN), "FUN")]
        [JsonSubtypes.KnownSubType(typeof(FUNTYPE), "FUNTYPE")]
    
    MaZiFAU's avatar
    MaZiFAU committed
        //[JsonSubtypes.KnownSubType(typeof(OMC<T>), "OMC<" + typeof(T).Name + ">")]
        [JsonSubtypes.KnownSubType(typeof(OMLIT<bool>), "OMLIT<Boolean>")]
        [JsonSubtypes.KnownSubType(typeof(OMLIT<byte>), "OMLIT<Byte>")]
        [JsonSubtypes.KnownSubType(typeof(OMLIT<short>), "OMLIT<Int16>")]
        [JsonSubtypes.KnownSubType(typeof(OMLIT<int>), "OMLIT<Int32>")]
        [JsonSubtypes.KnownSubType(typeof(OMLIT<long>), "OMLIT<Int64>")]
        [JsonSubtypes.KnownSubType(typeof(OMLIT<float>), "OMLIT<Single>")]
        [JsonSubtypes.KnownSubType(typeof(OMLIT<float>), "OMLIT<Double>")] // we dont use double
        [JsonSubtypes.KnownSubType(typeof(OMLIT<string>), "OMLIT<String>")]
        [JsonSubtypes.KnownSubType(typeof(OMLIT<Vector3>), "OMLIT<Vector3>")]
    
        [JsonSubtypes.FallBackSubType(typeof(FallbackWrapper))]
    
    MaZiFAU's avatar
    MaZiFAU committed
        //[JsonSubtypes.KnownSubType(typeof(FallbackWrapper), "SFunction")]
        //[JsonSubtypes.KnownSubTypeWithProperty(typeof(FallbackWrapper), "SFunction")]
    
        abstract public partial class SOMDoc
        {
            public string kind;
    
            protected SOMDoc() { kind = this.GetType().Name; }
    
    
            protected internal abstract SOMDoc SOMDocType(SOMDoc[] args, FUN.Param[] bound_params);
    
            public SOMDoc SOMDocType()
    
                => SOMDocType(new SOMDoc[0], new FUN.Param[0]);
    
            public static SOMDoc SOMDocType(Type type)
            {
                SOMDoc[] args = type.IsGenericType
                    ? type.GetGenericArguments().Select(t => SOMDocType(t)).ToArray()
    
                    : type.HasElementType ? new[] { SOMDocType(type.GetElementType()) }
    
                if (type == typeof(Vector3) // Isomoprhismus
                 || TupleExtensions.IsTupleType(type, out _)) // Dictionary does not like Generics
                    type = typeof(Tuple);
    
                if (type.HasElementType) // pretend its a List
    
                    type = typeof(List<>);
    
                if (type.IsGenericType) // Dictionary does not like Assembled Generics
                    type = type.GetGenericTypeDefinition();
    
    
    
                if (FuncExtensions.IsFuncType(type, out _))
    
                    return new FUNTYPE(args[..^1], args[^1]);
    
                if (MMTConstants.TYPE_TO_OMS.TryGetValue(type, out string uri))
    
                        ? new OMA(new OMS(uri), args)
                        : new OMS(uri);
    
    
                if (type.IsAnonymousType())
                    return new OMA(
                        new OMS(MMTConstants.MakeTypeType), 
                        type.GetFields()
                            .Select(mem => new OML_Member(mem.Name, SOMDocType(mem.FieldType), null))
                            .ToArray());
    
    
                throw new NotImplementedException($"For Type {type}");
    
    MaZiFAU's avatar
    MaZiFAU committed
            // change to SOMDoc[] args?
    
            protected internal abstract Type ToType(Type[] args, (string name, Type type)[] bound_params);
            public Type ToType()
    
                => ToType(new Type[0], new (string name, Type type)[0]);
    
    
            public static bool Equivalent(SOMDoc sd1, SOMDoc sd2)
                => sd1 != null && sd2 != null
                && sd1.Equivalent(sd2);
    
            public abstract bool Equivalent(SOMDoc sd2);
    
            public LambdaExpression GetLambdaExpression()
                => GetLambdaExpression(new LambdaExpression[0], new LambdaExpression[0], new ParameterExpression[0]);
    
            protected internal abstract LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params);
    
            public abstract override string ToString();
    
            public abstract SOMDoc MapURIs(Dictionary<string, string> old_to_new);
    
    
            public abstract string[] GetDependentFactIds();
    
    
            #region MakeMMT_OMS_URItoSOMDoc
    
    MaZiFAU's avatar
    MaZiFAU committed
            public static Vector3 MakeVector3(OMA tuple)
            {
    
    MaZiFAU's avatar
    MaZiFAU committed
                if (tuple.arguments is not OMLIT<float>[] xyz
    
    MaZiFAU's avatar
    MaZiFAU committed
                 || xyz.Length < 3)
    
                    throw new FormatException("Argument " + nameof(tuple) + "." + nameof(OMA.arguments)
    
    MaZiFAU's avatar
    MaZiFAU committed
                        + " expected to be: " + nameof(OMLIT<float>) + "[3]");
    
    MaZiFAU's avatar
    MaZiFAU committed
    
    
    MaZiFAU's avatar
    MaZiFAU committed
                return new Vector3((float)xyz[0].value, (float)xyz[1].value, (float)xyz[2].value);
    
    MaZiFAU's avatar
    MaZiFAU committed
            }
    
    
            public static OMA MakeVector3(Vector3 vec)
    
    MaZiFAU's avatar
    MaZiFAU committed
                        new OMLIT<float>(vec.x),
                        new OMLIT<float>(vec.y),
                        new OMLIT<float>(vec.z),
    
    
            public static OMA MakeTupel(SOMDoc[] args)
                => new(
                        new OMS(MMTConstants.Tuple),
                        args
                    );
    
            public static OMA MakeShallowList(SOMDoc[] args)
                => new(
                        new OMS(MMTConstants.ListApplicant),
                        args
                    );
    
    
            public static OMA MakeDeepList(SOMDoc[] args, SOMDoc SOMDoc_type)
    
            {
                SOMDoc[] end_of_list = new SOMDoc[] {
                    new OMA(
                        new OMS(MMTConstants.ListEnd),
                        new[] {
    
                        }
                    ),
                    args.Length == 0
                        ? null
                        : args[^1]
                };
    
                if (args.Length == 0)
                    end_of_list = end_of_list[..^0];
    
                SOMDoc defines = new OMA(
                    new OMS(MMTConstants.ListLiteral),
                    end_of_list
                );
    
                for (int i = args.Length - 2; i >= 0; i--)
                {
                    defines = new OMA(
                        new OMS(MMTConstants.ListLiteral),
                        new[] {
                            defines,
                            args[i],
                    });
                }
    
                SOMDoc type = new OMA(
    
                    new OMS(MMTConstants.ListType),
                    new[] { SOMDoc_type }
    
                );
    
                return new OMA(type, new[] { defines });
            }
            #endregion MakeMMT_OMS_URItoSOMDoc
        }
    
        public abstract class SOMDocCRTP<T> : SOMDoc where T : SOMDocCRTP<T>
        {
            protected SOMDocCRTP() : base() { }
    
            public override bool Equivalent(SOMDoc sd2)
                => this.GetType() == sd2.GetType() && (this as T).EquivalentWrapped(sd2 as T);
    
            protected abstract bool EquivalentWrapped(T sd2);
    
            public override SOMDoc MapURIs(Dictionary<string, string> old_to_new)
                => MapURIsWrapped(old_to_new);
    
            protected abstract T MapURIsWrapped(Dictionary<string, string> old_to_new);
        }
    
    
        public class FUNTYPE : SOMDocCRTP<FUNTYPE>
        {
            public new string kind = "FUNTYPE";
    
            public SOMDoc[] @params;
    
            public SOMDoc ret;
    
            [JsonConstructor]
            public FUNTYPE(SOMDoc[] @params, SOMDoc ret)
            {
                this.@params = @params;
                this.ret = ret;
            }
    
            public override string ToString()
                => "["
                + string.Join(", ", @params.Select(p => p.ToString()))
                + "] => {"
                + ret.ToString()
                + "}";
    
            protected override bool EquivalentWrapped(FUNTYPE sd2)
                => @params.Length == sd2.@params.Length
                && @params.Zip(sd2.@params, (a, b) => a.Equivalent(b))
                          .All(b => b)
                && ret.Equivalent(sd2.ret);
    
            protected override FUNTYPE MapURIsWrapped(Dictionary<string, string> old_to_new)
                => new(@params.Select(p => p.MapURIs(old_to_new)).ToArray()
                     , ret.MapURIs(old_to_new));
    
    
            public override string[] GetDependentFactIds()
                => new string[0];
    
    
            protected internal override LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params)
            {
                throw new NotImplementedException();
            }
    
    
            protected internal override SOMDoc SOMDocType(SOMDoc[] args, FUN.Param[] bound_params)
    
            {
                throw new NotImplementedException();
            }
    
    
            protected internal override Type ToType(Type[] args, (string name, Type type)[] bound_params)
    
                => FuncExtensions.CreateFuncType(Enumerable.Append(@params.Select(p => p.ToType()), ret.ToType()).ToArray());
    
        }
    
        public class FUN : SOMDocCRTP<FUN>
        {
            public new string kind = "FUN";
    
            public Param[] @params;
    
            public SOMDoc body;
    
            [JsonConstructor]
            public FUN(Param[] @params, SOMDoc body)
            {
                this.@params = @params;
                this.body = body;
            }
    
            public class Param
            {
                public string name;
    
                [JsonProperty("tp")]
                public SOMDoc type;
    
    
                [JsonConstructor]
                public Param(string name, SOMDoc tp)
                {
                    this.name = name;
    
                    this.type = tp;
    
    
                public override string ToString()
                    => name + "(" + type.ToString() + ")";
    
            }
    
            public override string ToString()
                => "["
    
                + string.Join(", ", @params.Select(p => p.ToString()))
    
                + "] => {"
                + body.ToString()
                + "}";
    
            protected override bool EquivalentWrapped(FUN sd2)
                => @params.Length == sd2.@params.Length
                && @params.Zip(sd2.@params, (a, b) => a.name.Equals(b.name)
    
                                                   && a.type.Equivalent(b.type))
    
                          .All(b => b)
                && body.Equivalent(sd2.body);
    
            protected override FUN MapURIsWrapped(Dictionary<string, string> old_to_new)
    
                => new(@params.Select(p => new Param(p.name, p.type.MapURIs(old_to_new))).ToArray()
    
                     , body.MapURIs(old_to_new));
    
    
            public override string[] GetDependentFactIds()
                => body.GetDependentFactIds();
    
    
            protected internal override LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params)
            {
    
                ParameterExpression[] local_param =
                    @params.Select(p => Expression.Parameter(p.type.ToType(), p.name)).ToArray();
    
    
                LambdaExpression body_lambda =
                    body.GetLambdaExpression(
                        lambda_applicant,
                        lambda_arguments,
                        bound_params.ShallowCloneAppend(local_param)
                    );
    
                return
                    Expression.Lambda(
                        Expression.Lambda(
                            body_lambda.Body,
                            local_param
                        ),
                        bound_params
                    );
    
            protected internal override SOMDoc SOMDocType(SOMDoc[] args, Param[] bound_params)
            {
                Param[] bind_me = bound_params.ShallowCloneAppend(@params);
    
                return new FUNTYPE(
                    @params.Select(p => p.type).ToArray(),
                    body.SOMDocType(new SOMDoc[0], bind_me)
                );
            }
    
            protected internal override Type ToType(Type[] args, (string name, Type type)[] bound_params)
            {
                (string name, Type)[] bind_me = bound_params
                    .AppendRange(@params.Select(p => (p.name, p.type.ToType())))
                    .ToArray();
    
                return SOMDocType().ToType(new Type[0], bind_me);
            }
    
    MaZiFAU's avatar
    MaZiFAU committed
        public class OMV : SOMDocCRTP<OMV>
    
    MaZiFAU's avatar
    MaZiFAU committed
            public new string kind = "VAR";
    
    
            public string name;
    
            [JsonConstructor]
    
    MaZiFAU's avatar
    MaZiFAU committed
            public OMV(string name) : base()
    
    MaZiFAU's avatar
    MaZiFAU committed
            protected override bool EquivalentWrapped(OMV sd2)
                => this.name == sd2.name;
    
            protected internal override SOMDoc SOMDocType(SOMDoc[] args, FUN.Param[] bound_params)
            {
                FUN.Param p = bound_params.FirstOrDefault(param => param.name.Equals(name))
                    ?? throw new FormatException($"Unable to find {nameof(FUN.Param)} for {nameof(OMV)} with name: {name}");
    
                return p.type;
            }
    
            protected internal override Type ToType(Type[] args, (string name, Type type)[] bound_params)
            {
                (string name, Type type) p = bound_params.FirstOrDefault(param => param.name.Equals(name));
    
    
                    throw new FormatException($"Unable to find {nameof(FUN.Param)} for {nameof(OMV)} with name: {name}");
    
                return p.type;
            }
    
    
            protected internal override LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params)
            {
    
    MaZiFAU's avatar
    MaZiFAU committed
                ParameterExpression v = bound_params.FirstOrDefault(param => param.Name.Equals(name));
                if (v == null)
                {
                    Debug.LogErrorFormat("Unable to find {0} for {1} with name: {2}", nameof(FUN.Param), nameof(OMV), name);
                    return Expression.Lambda(Expression.Empty(), null);
                }
                else
                    return Expression.Lambda(v, new[] { v });
    
            }
    
            public override string ToString()
    
    MaZiFAU's avatar
    MaZiFAU committed
                => "Variable_" + "(" + name + ")";
    
    MaZiFAU's avatar
    MaZiFAU committed
            protected override OMV MapURIsWrapped(Dictionary<string, string> old_to_new)
                => (OMV)this.MemberwiseClone();
    
    
            public override string[] GetDependentFactIds()
                => new string[0];
    
        }
    
        public class OMA : SOMDocCRTP<OMA>
        {
            public new string kind = "OMA";
    
            public SOMDoc applicant;
            public SOMDoc[] arguments;
    
            [JsonConstructor]
            public OMA(SOMDoc applicant, SOMDoc[] arguments) : base()
            {
                this.applicant = applicant;
                this.arguments = arguments;
            }
    
            protected override bool EquivalentWrapped(OMA sd2)
                => Equivalent(this.applicant, sd2.applicant)
                && this.arguments
                    .Zip(sd2.arguments, (arg1, arg2) => Equivalent(arg1, arg2))
                    .All(b => b);
    
    
            protected internal override LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_arguments_paps, LambdaExpression[] lambda_arguments_grands, ParameterExpression[] bound_params)
    
    MaZiFAU's avatar
    MaZiFAU committed
            {
                if (applicant is OMS OMSMake)
                    if (OMSMake.uri == MMTConstants.MakeType
                     || OMSMake.uri == MMTConstants.MakeTypeType)
                    {
                        KeyValuePair<string, LambdaExpression>[] members = arguments
                            .Select(arg => (OML_Member)arg)
                            .Select(rec => new KeyValuePair<string, LambdaExpression>(
                                rec.name,
                                (rec.defines ?? rec.of_type)
                                    .GetLambdaExpression(new LambdaExpression[0], new LambdaExpression[0], bound_params)))
                            .ToArray();
    
                        return SOMDocToLambdaExpression.MakeType(members, bound_params);
                    }
    
                return applicant.GetLambdaExpression(
                            arguments.Select(arg => arg.GetLambdaExpression(new LambdaExpression[0], new LambdaExpression[0], bound_params)).ToArray(),
                            lambda_arguments_paps,
                            bound_params
                        );
            }
    
            protected internal override SOMDoc SOMDocType(SOMDoc[] args, FUN.Param[] bound_params)
            {
                if (applicant is OMS OMSMake
                 && OMSMake.uri == MMTConstants.GetField)
                {
                    return (arguments[0] as OMA).arguments
                        .Select(arg => (OML_Member)arg) //RECTYPE?
                        .First(rec => rec.name == ((OML_Member)arguments[1]).name)
                        .defines.SOMDocType(new SOMDoc[0], bound_params);
                }
    
                return applicant.SOMDocType(
                            arguments.Select(a => a.SOMDocType(new SOMDoc[0], bound_params)).ToArray(),
                            bound_params
                        );
            }
    
            protected internal override Type ToType(Type[] args, (string name, Type type)[] bound_params)
            {
                if (applicant is OMS OMSMake)
                    if (OMSMake.uri == MMTConstants.MakeType
                     || OMSMake.uri == MMTConstants.MakeTypeType)
                    {
                        KeyValuePair<string, Type>[] members = arguments
                            .Select(arg => (OML_Member)arg)
                            .Select(rec => new KeyValuePair<string, Type>(
                                rec.name,
                                rec.of_type.ToType(new Type[0], bound_params)))
                            .ToArray();
    
                        return TupleFactory.Create(members).TupleType;
                    }
                    else
                    if (OMSMake.uri == MMTConstants.GetField)
                    {
                        return args[0].GetMember(((OML_Member)arguments[1]).name).First().ReflectedType;
                    }
    
                return applicant.ToType(
                            arguments.Select(arg => arg.ToType(new Type[0], bound_params)).ToArray(),
                            bound_params
                        );
            }
    
    
            public override string ToString()
                => applicant.ToString() + "(" + string.Join(", ", arguments.Select(a => a.ToString())) + ")";
    
            protected override OMA MapURIsWrapped(Dictionary<string, string> old_to_new)
                => new OMA(
                    applicant.MapURIs(old_to_new),
                    arguments.Select(arg => arg.MapURIs(old_to_new)).ToArray()
                );
    
            public override string[] GetDependentFactIds()
                => applicant.GetDependentFactIds()
                .AppendRange(arguments.SelectMany(arg => arg.GetDependentFactIds()))
                .ToArray();
    
        }
    
        public class OMS : SOMDocCRTP<OMS>
        {
            public new string kind = "OMS";
    
            public string uri;
    
            [JsonConstructor]
            public OMS(string uri) : base()
            {
                this.uri = uri;
            }
    
            protected override bool EquivalentWrapped(OMS sd2)
    
            {
                bool
                    b1 = FactRecorder.AllFacts.TryGetValue(uri, out Fact f1),
                    b2 = FactRecorder.AllFacts.TryGetValue(sd2.uri, out Fact f2);
    
                return (b1 == b2 && uri == sd2.uri)
                    || (b1 && b2 && f1.Equivalent(f2));
            }
    
    
            protected internal override LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_arguments_paps, LambdaExpression[] lambda_arguments_grands, ParameterExpression[] bound_params)
    
    MaZiFAU's avatar
    MaZiFAU committed
                => SOMDocToLambdaExpression.MakeLambdaExpression(uri, lambda_arguments_paps, lambda_arguments_grands, bound_params);
    
    
            public override string ToString()
                => uri;
    
            protected override OMS MapURIsWrapped(Dictionary<string, string> old_to_new)
            {
                if (!old_to_new.TryGetValue(uri, out string new_uri))
                    new_uri = uri;
    
                return new OMS(new_uri);
            }
    
            public override string[] GetDependentFactIds()
                => FactRecorder.AllFacts.ContainsKey(uri)
                ? new string[] { uri }
                : new string[0];
    
    
            protected internal override Type ToType(Type[] args, (string name, Type type)[] bound_params)
    
    MaZiFAU's avatar
    MaZiFAU committed
                if (FactRecorder.AllFacts.TryGetValue(uri, out Fact found))
    
                    return found.GetType();
    
                if (MMTConstants.HeterogenApplication_TO_TypeOF.TryGetValue(uri, out string s_type))
                {
                    Type type = MMTConstants.OMS_TO_TYPE[s_type];
    
                    if (type.Equals(typeof(Tuple)))
                    { // authors note: Not a fan, but has to be done somewhwere...
    
                        if (args.Length == 3
                         && args.All(t => t == typeof(float)))
                            return typeof(Vector3);
    
    
                        type = TupleExtensions.GetGenericTupleType(args.Length);
                    }
    
                    else
                    if (type.Equals(typeof(Func<>)))
                        return FuncExtensions.CreateFuncType(args);
    
                    return type
                        .MakeGenericType(args);
                }
    
                if (MMTConstants.HomogenApplication_TO_TypeOF.TryGetValue(uri, out s_type))
                    return MMTConstants.OMS_TO_TYPE[s_type]
                        .MakeGenericType(args[0]);
    
                if (MMTConstants.URI_TO_TypeOF.TryGetValue(uri, out s_type))
                    return MMTConstants.OMS_TO_TYPE[s_type];
    
                if (MMTConstants.OMS_TO_TYPE.TryGetValue(uri, out Type t_type))
                    return t_type;
    
                throw new NotImplementedException();
            }
    
    
            protected internal override SOMDoc SOMDocType(SOMDoc[] args, FUN.Param[] bound_params)
            {
                string _uri = uri;
                bool use_uri;
                if (use_uri = MMTConstants.OMS_TO_TYPE.TryGetValue(_uri, out Type tmp_type))
                    _uri = MMTConstants.TYPE_TO_OMS[tmp_type];
    
                if (FactRecorder.AllFacts.TryGetValue(_uri, out Fact found))
                    return new OMS(MMTConstants.TYPE_TO_OMS[found.GetType()]);
    
                if (MMTConstants.HeterogenApplication_TO_TypeOF.TryGetValue(_uri, out string type))
                    return new OMA(
                        new OMS(type),
                        args
                    );
    
                if (MMTConstants.HomogenApplication_TO_TypeOF.TryGetValue(_uri, out type))
                    return new OMA(
                        new OMS(type),
                        new[] { args[0] }
                    );
    
                if (MMTConstants.URI_TO_TypeOF.TryGetValue(_uri, out type))
                    return new OMS(type);
    
                if (use_uri)
                    return SOMDocType(tmp_type);
    
    
                throw new NotImplementedException(uri);
            }
    
    MaZiFAU's avatar
    MaZiFAU committed
        public class RAW : SOMDocCRTP<RAW>
    
    MaZiFAU's avatar
    MaZiFAU committed
            public new string kind = "RAW";
    
    MaZiFAU's avatar
    MaZiFAU committed
            public string xml;
    
    MaZiFAU's avatar
    MaZiFAU committed
            public RAW(string xml) : base()
    
    MaZiFAU's avatar
    MaZiFAU committed
                this.xml = xml;
    
            protected internal override SOMDoc SOMDocType(SOMDoc[] args, FUN.Param[] bound_params)
    
    MaZiFAU's avatar
    MaZiFAU committed
                => throw new NotSupportedException();
    
            protected override RAW MapURIsWrapped(Dictionary<string, string> old_to_new)
            {
                string copy = xml;
                foreach (KeyValuePair<string, string> KeyVal in old_to_new)
                    copy = copy.Replace(KeyVal.Key, KeyVal.Value);
    
    MaZiFAU's avatar
    MaZiFAU committed
                return new RAW(copy);
            }
    
    MaZiFAU's avatar
    MaZiFAU committed
            public override string[] GetDependentFactIds()
                => new string[0];
    
    
            public override string ToString()
    
    MaZiFAU's avatar
    MaZiFAU committed
                => xml;
    
    MaZiFAU's avatar
    MaZiFAU committed
            protected override bool EquivalentWrapped(RAW sd2)
                => throw new NotImplementedException(); //xml == sd2.xml; // only exact
    
    MaZiFAU's avatar
    MaZiFAU committed
            protected internal override LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params)
                => throw new NotSupportedException();
    
            protected internal override Type ToType(Type[] args, (string name, Type type)[] bound_params)
    
    MaZiFAU's avatar
    MaZiFAU committed
                => throw new NotSupportedException();
    
    MaZiFAU's avatar
    MaZiFAU committed
        // tp == null && df == null: member access
        // tp != null : member/type declaration
        // df != null : member value
        public class OML_Member : SOMDocCRTP<OML_Member>
    
    MaZiFAU's avatar
    MaZiFAU committed
            public new string kind = "OML";
    
            [JsonProperty("name")]
            public string name;
    
            [JsonProperty("tp")]
            public SOMDoc of_type;
    
    MaZiFAU's avatar
    MaZiFAU committed
            [JsonProperty("df")]
            public SOMDoc defines;
    
    MaZiFAU's avatar
    MaZiFAU committed
            public OML_Member(string name, SOMDoc of_type, SOMDoc defines)
    
    MaZiFAU's avatar
    MaZiFAU committed
                this.name = name;
                this.of_type = of_type;
                this.defines = defines;
    
    MaZiFAU's avatar
    MaZiFAU committed
            public override string[] GetDependentFactIds()
                => defines?.GetDependentFactIds() ?? new string[0];
    
    MaZiFAU's avatar
    MaZiFAU committed
            public override string ToString()
            {
                string tp = of_type == null ? string.Empty : $": {of_type}";
                string df = defines == null ? string.Empty : $" = {{{defines}}}";
                return $".{name}" + tp + df;
            }
    
    MaZiFAU's avatar
    MaZiFAU committed
            protected override bool EquivalentWrapped(OML_Member sd2)
                => name == sd2.name
                && ((of_type == null && sd2.of_type == null) || of_type.Equivalent(sd2.of_type))
                && ((defines == null && sd2.defines == null) || defines.Equivalent(sd2.defines));
    
    MaZiFAU's avatar
    MaZiFAU committed
            protected override OML_Member MapURIsWrapped(Dictionary<string, string> old_to_new)
                => new(name, of_type?.MapURIs(old_to_new), defines?.MapURIs(old_to_new));
    
    MaZiFAU's avatar
    MaZiFAU committed
            protected internal override LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params)
                => defines == null && of_type == null
                ? Expression.Lambda(Expression.Constant(name, typeof(string))) // PropertyInfo? => would need info about sister element in OMA.arguments
                : throw new NotSupportedException(); //=> new KeyValuePair<string, Expression>(name, value.GetLambdaExpression(lambda_applicant, lambda_arguments, bound_params))
    
    MaZiFAU's avatar
    MaZiFAU committed
            protected internal override SOMDoc SOMDocType(SOMDoc[] args, FUN.Param[] bound_params)
                => new OML_Member(
                        name,
                        of_type
                        ?? defines?.SOMDocType(args, bound_params)
                        ?? throw new NotSupportedException(), // would need info about sister element in OMA.arguments
                        null
                    );
    
            protected internal override Type ToType(Type[] args, (string name, Type type)[] bound_params)
    
    MaZiFAU's avatar
    MaZiFAU committed
                => defines?.ToType(args, bound_params)
                //?? of_type?.ToType(args, bound_params) //is Member Declaration not Member Type
                ?? throw new NotSupportedException(); // would need info about sister element in OMA.arguments
    
    MaZiFAU's avatar
    MaZiFAU committed
        public class OMLIT<T> : SOMDocCRTP<OMLIT<T>>
    
    MaZiFAU's avatar
    MaZiFAU committed
            public new string kind = "OMLIT<" + typeof(T).Name + ">";
    
    MaZiFAU's avatar
    MaZiFAU committed
            public string type;
    
            public T value;
    
    MaZiFAU's avatar
    MaZiFAU committed
            public OMLIT(T value, string type = null) : base()
    
    MaZiFAU's avatar
    MaZiFAU committed
                this.value = value;
                this.type = type ?? MMTConstants.TYPE_TO_OMS[value.GetType()];
    
            protected internal override SOMDoc SOMDocType(SOMDoc[] args, FUN.Param[] bound_params)
    
    MaZiFAU's avatar
    MaZiFAU committed
                => SOMDocType(typeof(T));
    
    MaZiFAU's avatar
    MaZiFAU committed
            protected override bool EquivalentWrapped(OMLIT<T> sd2)
                => ApproximationComparer.Instance.Equals(value, sd2);
    
    MaZiFAU's avatar
    MaZiFAU committed
            protected internal override LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params)
                => Expression.Lambda(Expression.Constant(value, typeof(T)), null);
    
    MaZiFAU's avatar
    MaZiFAU committed
            public override string ToString()
    
    MaZiFAU's avatar
    MaZiFAU committed
                => value.ToString();
    
    MaZiFAU's avatar
    MaZiFAU committed
            protected override OMLIT<T> MapURIsWrapped(Dictionary<string, string> old_to_new)
                => (OMLIT<T>)this.MemberwiseClone();
    
    MaZiFAU's avatar
    MaZiFAU committed
            public override string[] GetDependentFactIds()
                => new string[0];
    
            protected internal override Type ToType(Type[] args, (string name, Type type)[] bound_params)
    
    MaZiFAU's avatar
    MaZiFAU committed
                => typeof(T);
    
        // temporary fix if Serialzation is broken
        public class FallbackWrapper : SOMDocCRTP<FallbackWrapper>
    
    MaZiFAU's avatar
    MaZiFAU committed
            public new string kind = "SFunction";
    
    
            public FallbackWrapper(SOMDoc SFunction)
    
            {
                this.SFunction = SFunction;
            }
    
            public override string ToString()
                => SFunction.ToString();
    
    
            protected override bool EquivalentWrapped(FallbackWrapper sd2)
    
            protected override FallbackWrapper MapURIsWrapped(Dictionary<string, string> old_to_new)
    
                => new(SFunction.MapURIs(old_to_new));
    
            protected internal override LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params)
                => SFunction.GetLambdaExpression(lambda_applicant, lambda_arguments, bound_params);
    
    
            protected internal override SOMDoc SOMDocType(SOMDoc[] args, FUN.Param[] bound_params)
                => SFunction.SOMDocType(args, bound_params);
    
            protected internal override Type ToType(Type[] args, (string name, Type type)[] bound_params)
                => SFunction.ToType(args, bound_params);
    
    
            public override string[] GetDependentFactIds()
                => SFunction.GetDependentFactIds();