Skip to content
Snippets Groups Projects
SOMDocs.cs 25.3 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
    {
        [JsonConverter(typeof(JsonSubtypes), "kind")]
        [JsonSubtypes.KnownSubType(typeof(OMA), "OMA")]
        [JsonSubtypes.KnownSubType(typeof(OMS), "OMS")]
        [JsonSubtypes.KnownSubType(typeof(OMSTR), "OMSTR")]
        [JsonSubtypes.KnownSubType(typeof(OMF), "OMF")]
    
        [JsonSubtypes.KnownSubType(typeof(OMV), "VAR")]
    
        [JsonSubtypes.KnownSubType(typeof(RAW), "RAW")]
    
        [JsonSubtypes.KnownSubType(typeof(FUN), "FUN")]
        [JsonSubtypes.KnownSubType(typeof(FUNTYPE), "FUNTYPE")]
    
        //[JsonSubtypes.KnownSubType(typeof(OMC<T>), "OMC<" + typeof(T) + ">")]
        [JsonSubtypes.KnownSubType(typeof(OMC<Vector3>), "OMC<UnityEngine.Vector3>")]
        [JsonSubtypes.KnownSubType(typeof(OMC<float>), "OMC<System.Single>")]
        [JsonSubtypes.KnownSubType(typeof(OMC<double>), "OMC<System.Double>")]
    
        [JsonSubtypes.FallBackSubType(typeof(FallbackWrapper))]
    
        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)
            {
                if (type == typeof(Vector3)) // Isomoprhismus
                    type = typeof(Tuple);
    
                SOMDoc[] args = type.IsGenericType
                    ? type.GetGenericArguments().Select(t => SOMDocType(t)).ToArray()
                    : null;
    
                if (FuncExtensions.GenericFuncTypes.Contains(type.IsGenericType ? type.GetGenericTypeDefinition() : type))
                    return new FUNTYPE(args[..^1], args[^1]);
    
                if (MMTConstants.TYPE_TO_OMS.TryGetValue(type, out string uri))
                    return type.IsGenericType
                        ? new OMA(new OMS(uri), args)
                        : new OMS(uri);
    
                throw new NotImplementedException();
            }
    
            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 Func<object[], object[]> PartialInvokeCastingLambdaExpression(out Type[] signature_args, object[] callArgs = null, bool[] useArgs = null)
    
            {
                LambdaExpression lambda_orig = GetLambdaExpression();
    
                if (lambda_orig.Body is LambdaExpression lambda_lambda)
                    lambda_orig = lambda_lambda;
    
    
                signature_args = new Type[lambda_orig.Parameters.Count + 1];
    
                ParameterExpression object_arr = Expression.Parameter(typeof(object[]), "PARAMS_Arr");
                Expression[] cast_new_to_signature = new Expression[lambda_orig.Parameters.Count];
    
                int n_params = 0;
                for (int i = 0; i < lambda_orig.Parameters.Count; i++)
                {
                    if (callArgs != null && callArgs.Length < i
                     && (useArgs == null || (useArgs.Length < i && useArgs[i])))
                    {
                        cast_new_to_signature[i] =
                            Expression.Constant(callArgs[i], lambda_orig.Parameters[i].Type);
                        continue;
                    }
    
                    signature_args[n_params++] = lambda_orig.Parameters[i].Type;
    
                    cast_new_to_signature[i] =
                        Expression.Convert(
                            Expression.ArrayIndex(
                                object_arr,
                                Expression.Constant(i)
                            ),
                            lambda_orig.Parameters[i].Type
                        );
                }
                signature_args[n_params] = lambda_orig.ReturnType;
                signature_args = signature_args.Slice(0, n_params + 1).ToArray();
    
    
                LambdaExpression final_expression =
                    Expression.Lambda(
    
                        typeof(object[]).IsAssignableFrom(lambda_orig.ReturnType)
                        ? Expression.Invoke(lambda_orig, cast_new_to_signature)
                        : Expression.NewArrayInit(
                            typeof(object),
                            new Expression[] { Expression.Convert(Expression.Invoke(lambda_orig, cast_new_to_signature), typeof(object)) }),
    
                return final_expression.Compile() as Func<object[], object[]>;
    
            }
    
            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);
    
            #region MakeMMT_OMS_URItoSOMDoc
    
    MaZiFAU's avatar
    MaZiFAU committed
            public static Vector3 MakeVector3(OMA tuple)
            {
                if (tuple.arguments is not OMF[] xyz
                 || xyz.Length < 3)
    
                    throw new FormatException("Argument " + nameof(tuple) + "." + nameof(OMA.arguments)
    
    MaZiFAU's avatar
    MaZiFAU committed
                        + " expected to be: " + nameof(OMF) + "[3]");
    
                return new Vector3(xyz[0].@float, xyz[1].@float, xyz[2].@float);
            }
    
    
            public static OMA MakeVector3(Vector3 vec)
    
                => MakeTupel(new[] {
                        new OMF(vec.x),
                        new OMF(vec.y),
                        new OMF(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));
    
            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));
    
            protected internal override LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params)
            {
                ParameterExpression[] bind_me = bound_params.ShallowCloneAppend(
    
                    @params.Select(p => Expression.Parameter(p.type.ToType(), p.name)).ToArray()
    
                );
    
                return Expression.Lambda(
                    body.GetLambdaExpression(lambda_applicant, lambda_arguments, bind_me),
                    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));
    
                if(p == default)
                    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 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 internal override SOMDoc SOMDocType(SOMDoc[] args, FUN.Param[] bound_params)
                => applicant.SOMDocType(
                    arguments.Select(a => a.SOMDocType(new SOMDoc[0], bound_params)).ToArray(),
                    bound_params
                );
    
    
            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)
    
                => applicant.GetLambdaExpression(
                    arguments.Select(arg => arg.GetLambdaExpression(new LambdaExpression[0], new LambdaExpression[0], bound_params)).ToArray(),
    
                    lambda_arguments_paps,
    
                    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()
                );
    
            protected internal override Type ToType(Type[] args, (string name, Type type)[] bound_params)
                => applicant.ToType(
                    arguments.Select(arg => arg.ToType(new Type[0], bound_params)).ToArray(),
                    bound_params
                );
    
        }
    
        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)
                => this.uri == sd2.uri;
    
    
            protected internal override LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_arguments_paps, LambdaExpression[] lambda_arguments_grands, ParameterExpression[] bound_params)
                => SOMDocToLambdaExpression<float>.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);
            }
    
            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);
                    //return new OMS(_uri);
    
                throw new NotImplementedException(uri);
            }
    
        }
    
        public class OMSTR : SOMDocCRTP<OMSTR>
        {
            public new string kind = "OMSTR";
    
            [JsonProperty("float")]
            public string s;
    
            [JsonConstructor]
            public OMSTR(string s) : base()
            {
                this.s = s;
            }
    
    
            protected internal override SOMDoc SOMDocType(SOMDoc[] args, FUN.Param[] bound_params)
    
                => throw new NotImplementedException();
    
            protected override bool EquivalentWrapped(OMSTR sd2)
                => this.s == sd2.s;
    
            protected internal override LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params)
                => Expression.Lambda(Expression.Constant(s, typeof(string)), null);
    
            public override string ToString()
                => s;
    
            protected override OMSTR MapURIsWrapped(Dictionary<string, string> old_to_new)
                => (OMSTR)this.MemberwiseClone();
    
            protected internal override Type ToType(Type[] args, (string name, Type type)[] bound_params)
    
                => typeof(string);
    
        }
    
        public class OMF : SOMDocCRTP<OMF>
        {
            public new string kind = "OMF";
    
            [JsonProperty("float")]
            public float @float;
    
            [JsonConstructor]
            public OMF(float f) : base()
            {
                this.@float = f;
            }
    
    
            protected internal override SOMDoc SOMDocType(SOMDoc[] args, FUN.Param[] bound_params)
    
                => new OMS(MMTConstants.RealLit);
    
            protected override bool EquivalentWrapped(OMF sd2)
                => Mathf.Approximately(@float, sd2.@float);
    
            protected internal override LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params)
                => Expression.Lambda(Expression.Constant(@float, typeof(float)), null);
    
            public override string ToString()
                => @float.ToString();
    
            protected override OMF MapURIsWrapped(Dictionary<string, string> old_to_new)
                => (OMF)this.MemberwiseClone();
    
            protected internal override Type ToType(Type[] args, (string name, Type type)[] bound_params)
    
                => typeof(float);
    
    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)
                => throw new NotSupportedException();
    
    MaZiFAU's avatar
    MaZiFAU committed
            protected override RAW MapURIsWrapped(Dictionary<string, string> old_to_new)
    
    MaZiFAU's avatar
    MaZiFAU committed
                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 ToString()
                => xml;
    
    MaZiFAU's avatar
    MaZiFAU committed
            protected override bool EquivalentWrapped(RAW sd2)
                => throw new NotImplementedException(); //xml == sd2.xml; // only exact
    
    
            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)
                => throw new NotSupportedException();
    
        // temporary fix if Serialzation is broken
        public class FallbackWrapper : SOMDocCRTP<FallbackWrapper>
    
            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);
    
    MaZiFAU's avatar
    MaZiFAU committed
        // internal use only
        public class OMC<T> : SOMDocCRTP<OMC<T>>
    
    MaZiFAU's avatar
    MaZiFAU committed
            public new string kind = "OMC<" + typeof(T) + ">";
    
    MaZiFAU's avatar
    MaZiFAU committed
            public T value;
    
    MaZiFAU's avatar
    MaZiFAU committed
            public OMC(T value) : base()
    
    MaZiFAU's avatar
    MaZiFAU committed
                this.value = value;
    
            protected internal override SOMDoc SOMDocType(SOMDoc[] args, FUN.Param[] bound_params)
                => SOMDocType(typeof(T));
    
    MaZiFAU's avatar
    MaZiFAU committed
            protected override bool EquivalentWrapped(OMC<T> sd2)
    
    MaZiFAU's avatar
    MaZiFAU committed
                Debug.LogWarning("Cannot check Equivalency for " + this.GetType() + "; only whether it's exact!");
                return this.value.Equals(value);
    
    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()
                => "C_" + typeof(T) + "(" + value.ToString() + ")";
    
    MaZiFAU's avatar
    MaZiFAU committed
            protected override OMC<T> MapURIsWrapped(Dictionary<string, string> old_to_new)
                => (OMC<T>)this.MemberwiseClone();
    
            protected internal override Type ToType(Type[] args, (string name, Type type)[] bound_params)
    
    MaZiFAU's avatar
    MaZiFAU committed
                => typeof(T);