Exemplo n.º 1
0
        public static Dictionary <string, (List <Type> Types, string inFunction)> UsedParameters(
            this ProfileMetaData profile, Context context)
        {
            var parameters = new Dictionary <string, (List <Type> Types, string usageLocation)>();


            void AddParams(IExpression e, string inFunction)
            {
                var parms = e.UsedParameters();

                foreach (var param in parms)
                {
                    if (parameters.TryGetValue(param.ParamName, out var typesOldUsage))
                    {
                        var(types, oldUsage) = typesOldUsage;
                        var unified = types.SpecializeTo(param.Types);
                        if (unified == null)
                        {
                            throw new ArgumentException("Inconsistent parameter usage: the paremeter " +
                                                        param.ParamName + " is used\n" +
                                                        $"   in {oldUsage} as {string.Join(",", types)}\n" +
                                                        $"   in {inFunction} as {string.Join(",", param.Types)}\n" +
                                                        $"which can not be unified");
                        }
                    }
                    else
                    {
                        parameters[param.ParamName] = (param.Types.ToList(), inFunction);
                    }
                }
            }

            AddParams(profile.Access, "profile definition for " + profile.Name + ".access");
            AddParams(profile.Oneway, "profile definition for " + profile.Name + ".oneway");
            AddParams(profile.Speed, "profile definition for " + profile.Name + ".speed");

            foreach (var(key, expr) in profile.Priority)
            {
                AddParams(new Parameter(key), profile.Name + ".priority.lefthand");
                AddParams(expr, profile.Name + ".priority");
            }

            var calledFunctions = profile.CalledFunctionsRecursive(context).Values
                                  .SelectMany(ls => ls).ToHashSet();

            foreach (var calledFunction in calledFunctions)
            {
                var func = context.GetFunction(calledFunction);
                if (func is AspectMetadata meta && meta.ProfileInternal)
                {
                    continue;
                }

                AddParams(func, "function " + calledFunction);
            }


            return(parameters);
        }
Exemplo n.º 2
0
        public static Dictionary <string, IExpression> MembershipMappingsFor(ProfileMetaData profile, Context context)
        {
            var calledFunctions = profile.Priority.Values.ToHashSet();

            calledFunctions.Add(profile.Speed);
            calledFunctions.Add(profile.Access);
            calledFunctions.Add(profile.Oneway);


            var calledFunctionQueue      = new Queue <string>();
            var alreadyAnalysedFunctions = new HashSet <string>();
            var memberships = new Dictionary <string, IExpression>();

            void HandleExpression(IExpression e, string calledIn)
            {
                e.Visit(f =>
                {
                    var mapping = new List <IExpression>();
                    if (Deconstruct.UnApply(Deconstruct.IsFunc(Funcs.MemberOf),
                                            Deconstruct.Assign(mapping)
                                            ).Invoke(f))
                    {
                        memberships.Add(calledIn, mapping.First());
                        return(false);
                    }

                    if (f is FunctionCall fc)
                    {
                        calledFunctionQueue.Enqueue(fc.CalledFunctionName);
                    }

                    return(true);
                });
            }

            foreach (var e in calledFunctions)
            {
                HandleExpression(e, "profile_root");
            }

            while (calledFunctionQueue.TryDequeue(out var functionName))
            {
                if (alreadyAnalysedFunctions.Contains(functionName))
                {
                    continue;
                }

                alreadyAnalysedFunctions.Add(functionName);

                var functionImplementation = context.GetFunction(functionName);
                HandleExpression(functionImplementation, functionName);
            }


            return(memberships);
        }
Exemplo n.º 3
0
 public LuaPrinter1(ProfileMetaData profile, Context context,
                    List <AspectTestSuite> aspectTestSuites,
                    List <BehaviourTestSuite> profileTests)
 {
     _profile          = profile;
     _context          = context;
     _aspectTestSuites = aspectTestSuites?.Where(suite => suite != null)
                         ?.Select(testSuite => testSuite.WithoutRelationTests())?.ToList();
     _profileTests     = profileTests;
     _skeleton         = new LuaSkeleton.LuaSkeleton(context, false);
     _parameterPrinter = new LuaParameterPrinter(profile, _skeleton);
 }
Exemplo n.º 4
0
 public LuaPrinter2(ProfileMetaData profile, string behaviourName,
                    Context context,
                    List <AspectTestSuite> aspectTests, IEnumerable <BehaviourTestSuite> behaviourTestSuite,
                    DateTime lastChangeTime)
 {
     _skeleton           = new LuaSkeleton.LuaSkeleton(context, true);
     _profile            = profile;
     _behaviourName      = behaviourName;
     _context            = context;
     _aspectTests        = aspectTests;
     _behaviourTestSuite = behaviourTestSuite;
     _lastChangeTime     = lastChangeTime;
     _parameterPrinter   = new LuaParameterPrinter(_profile, _skeleton);
 }
Exemplo n.º 5
0
        public static Dictionary <string, List <string> > CalledFunctionsRecursive(this ProfileMetaData profile,
                                                                                   Context c)
        {
            // Read as: this function calls the value-function
            var result = new Dictionary <string, List <string> >();


            var calledFunctions = new Queue <string>();

            void ScanExpression(IExpression e, string inFunction)
            {
                if (!result.ContainsKey(inFunction))
                {
                    result.Add(inFunction, new List <string>());
                }

                e.Visit(x =>
                {
                    if (x is FunctionCall fc)
                    {
                        result[inFunction].Add(fc.CalledFunctionName);
                        if (!result.ContainsKey(fc.CalledFunctionName))
                        {
                            calledFunctions.Enqueue(fc.CalledFunctionName);
                        }
                    }

                    return(true);
                });
            }

            ScanExpression(profile.Access, profile.Name + ".access");
            ScanExpression(profile.Oneway, profile.Name + ".oneway");
            ScanExpression(profile.Speed, profile.Name + ".speed");

            foreach (var(key, expr) in profile.Priority)
            {
                ScanExpression(new Parameter(key), $"{profile.Name}.priority.{key}.lefthand");
                ScanExpression(expr, $"{profile.Name}.priority.{key}");
            }

            while (calledFunctions.TryDequeue(out var calledFunction))
            {
                var func = c.GetFunction(calledFunction);
                ScanExpression(func, calledFunction);
            }


            return(result);
        }
Exemplo n.º 6
0
        private static void PrintUsedTags(ProfileMetaData profile, Context context)
        {
            Console.WriteLine("\n\n\n---------- " + profile.Name + " --------------");
            foreach (var(key, values) in profile.AllExpressions(context).PossibleTags())
            {
                var vs = "*";
                if (values.Any())
                {
                    vs = string.Join(", ", values);
                }

                Console.WriteLine(key + ": " + vs);
            }

            Console.WriteLine("\n\n\n------------------------");
        }
Exemplo n.º 7
0
        private static void Repl(Context c, Dictionary <string, ProfileMetaData> profiles)
        {
            var profile   = profiles["emergency_vehicle"];
            var behaviour = profile.Behaviours.Keys.First();

            do
            {
                Console.Write(profile.Name + "." + behaviour + " > ");
                var read = Console.ReadLine();
                if (read == null)
                {
                    return;               // End of stream has been reached
                }
                if (read == "")
                {
                    Console.WriteLine("looƆ sᴉ dɐWʇǝǝɹʇSuǝdO");
                    continue;
                }

                if (read.Equals("quit"))
                {
                    return;
                }

                if (read.Equals("help"))
                {
                    Console.WriteLine(
                        Utils.Lines("select <behaviourName> to change behaviour or <vehicle.behaviourName> to change vehicle",
                                    ""));
                    continue;
                }

                if (read.Equals("clear"))
                {
                    for (var i = 0; i < 80; i++)
                    {
                        Console.WriteLine();
                    }

                    continue;
                }

                if (read.StartsWith("select"))
                {
                    var beh = read.Substring("select".Length + 1).Trim();

                    if (beh.Contains("."))
                    {
                        var profileName = beh.Split(".")[0];
                        if (!profiles.TryGetValue(profileName, out var newProfile))
                        {
                            Console.Error.WriteLine("Profile " + profileName + " not found, ignoring");
                            continue;
                        }

                        profile = newProfile;
                        beh     = beh.Substring(beh.IndexOf(".") + 1);
                    }

                    if (profile.Behaviours.ContainsKey(beh))
                    {
                        behaviour = beh;
                        Console.WriteLine("Switched to " + beh);
                    }
                    else
                    {
                        Console.WriteLine("Behaviour not found. Known behaviours are:\n   " +
                                          string.Join("\n   ", profile.Behaviours.Keys));
                    }


                    continue;
                }

                var tagsRaw = read.Split(";").Select(s => s.Trim());
                var tags    = new Dictionary <string, string>();
                foreach (var str in tagsRaw)
                {
                    if (str == "")
                    {
                        continue;
                    }

                    var strSplit = str.Split("=");
                    var k        = strSplit[0].Trim();
                    var v        = strSplit[1].Trim();
                    tags[k] = v;
                }

                try
                {
                    var result = profile.Run(c, behaviour, tags);
                    Console.WriteLine(result);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    Console.WriteLine(e.Message);
                }
            } while (true);
        }
 public LuaParameterPrinter(ProfileMetaData profile, LuaSkeleton.LuaSkeleton skeleton)
 {
     _profile  = profile;
     _skeleton = skeleton;
 }
Exemplo n.º 9
0
        public static void SanityCheckProfile(this ProfileMetaData pmd, Context context)
        {
            var defaultParameters = pmd.DefaultParameters.Keys
                                    .Select(k => k.TrimStart('#')).ToList();


            var usedMetadata = pmd.UsedParameters(context);

            string MetaList(IEnumerable <string> paramNames)
            {
                var metaInfo = "";

                foreach (var paramName in paramNames)
                {
                    var _ = usedMetadata.TryGetValue(paramName, out var inFunction) ||
                            usedMetadata.TryGetValue('#' + paramName, out inFunction);
                    metaInfo += $"\n - {paramName} (used in {inFunction.inFunction})";
                }

                return(metaInfo);
            }

            var usedParameters = usedMetadata.Keys.Select(key => key.TrimStart('#')).ToList();

            var diff = usedParameters.ToHashSet().Except(defaultParameters).ToList();

            if (diff.Any())
            {
                throw new ArgumentException("No default value set for parameter: " + MetaList(diff));
            }

            var unused = defaultParameters.Except(usedParameters);

            if (unused.Any())
            {
                Console.WriteLine("[WARNING] A default value is set for parameter, but it is unused: " +
                                  string.Join(", ", unused));
            }

            var paramsUsedInBehaviour = new HashSet <string>();

            foreach (var(behaviourName, behaviourParams) in pmd.Behaviours)
            {
                var sum         = 0.0;
                var explanation = "";
                paramsUsedInBehaviour.UnionWith(behaviourParams.Keys.Select(k => k.Trim('#')));
                foreach (var(paramName, _) in pmd.Priority)
                {
                    if (!pmd.DefaultParameters.ContainsKey(paramName))
                    {
                        throw new ArgumentException(
                                  $"The behaviour {behaviourName} uses a parameter for which no default is set: {paramName}");
                    }

                    if (!behaviourParams.TryGetValue(paramName, out var weight))
                    {
                        explanation += $"\n - {paramName} = default (not set)";
                        continue;
                    }

                    var weightObj = weight.Evaluate(context);

                    if (!(weightObj is double d))
                    {
                        throw new ArgumentException(
                                  $"The parameter {paramName} is not a numeric value in profile {behaviourName}");
                    }

                    sum         += Math.Abs(d);
                    explanation += $"\n - {paramName} = {d}";
                }

                if (Math.Abs(sum) < 0.0001)
                {
                    throw new ArgumentException("Profile " + behaviourName +
                                                ": the summed parameters to calculate the weight are zero or very low:" +
                                                explanation);
                }
            }


            var defaultOnly = defaultParameters.Except(paramsUsedInBehaviour).ToList();

            if (defaultOnly.Any())
            {
                Console.WriteLine(
                    $"[{pmd.Name}] WARNING: Some parameters only have a default value: {string.Join(", ", defaultOnly)}");
            }
        }