Add scaling factor to profiles
This commit is contained in:
parent
43590ad69f
commit
d80bff69d7
4 changed files with 52 additions and 61 deletions
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using AspectedRouting.IO.LuaSkeleton;
|
||||
using AspectedRouting.IO.LuaSnippets;
|
||||
using AspectedRouting.Language;
|
||||
using AspectedRouting.Language.Functions;
|
||||
using AspectedRouting.Language.Typ;
|
||||
|
@ -18,7 +18,7 @@ namespace AspectedRouting.IO.itinero1
|
|||
var access = _skeleton.ToLuaWithTags(_profile.Access);
|
||||
var oneway = _skeleton.ToLuaWithTags(_profile.Oneway);
|
||||
var speed = _skeleton.ToLuaWithTags(_profile.Speed);
|
||||
|
||||
|
||||
var impl = string.Join("\n",
|
||||
"",
|
||||
"",
|
||||
|
@ -54,16 +54,17 @@ namespace AspectedRouting.IO.itinero1
|
|||
impl +=
|
||||
"\n local priority = 0\n ";
|
||||
|
||||
var tags = new LuaLiteral(Typs.Tags, "tags");
|
||||
foreach (var (parameterName, expression) in _profile.Priority)
|
||||
{
|
||||
var paramInLua = _skeleton.ToLua(new Parameter(parameterName));
|
||||
|
||||
|
||||
var expr = Funcs.Either(Funcs.Id, Funcs.Const, expression).Apply(new LuaLiteral(Typs.Tags, "tags"))
|
||||
var expr = Funcs.Either(Funcs.Id, Funcs.Const, expression).Apply(tags)
|
||||
.SpecializeToSmallestType()
|
||||
.PruneTypes(t => !(t is Curry))
|
||||
.Optimize(out _);
|
||||
|
||||
|
||||
if (expr.Types.Any(t => t.Name.Equals(Typs.Bool.Name)))
|
||||
{
|
||||
expr = Funcs.Parse.Apply(expr).SpecializeToSmallestType();
|
||||
|
@ -77,8 +78,14 @@ namespace AspectedRouting.IO.itinero1
|
|||
);
|
||||
}
|
||||
|
||||
var scalingFactor = Funcs.Default.Apply(new Constant(Typs.Double, 1.0), _profile.ScalingFactor, tags);
|
||||
|
||||
impl += string.Join("\n",
|
||||
" -- Calculate the scaling factor",
|
||||
" local scalingfactor",
|
||||
Snippets.Convert(_skeleton, "scalingfactor", scalingFactor.SpecializeToSmallestType()),
|
||||
"",
|
||||
"priority = priority * scalingfactor",
|
||||
"",
|
||||
"",
|
||||
" if (priority <= 0) then",
|
||||
|
@ -100,10 +107,10 @@ namespace AspectedRouting.IO.itinero1
|
|||
"end"
|
||||
);
|
||||
|
||||
return impl;
|
||||
return impl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private (string functionName, string implementation) GenerateBehaviourFunction(
|
||||
string behaviourName,
|
||||
Dictionary<string, IExpression> behaviourParameters)
|
||||
|
@ -115,12 +122,12 @@ namespace AspectedRouting.IO.itinero1
|
|||
_skeleton.AddDep("copy_tags");
|
||||
var usedkeys = _profile.AllExpressionsFor(behaviourName, _context)
|
||||
.PossibleTagsRecursive(_context)
|
||||
.Select(t => "\""+ t.Key+"\"")
|
||||
.Select(t => "\"" + t.Key + "\"")
|
||||
.ToHashSet();
|
||||
|
||||
_skeleton.AddDep("remove_relation_prefix");
|
||||
var impl = string.Join("\n",
|
||||
"behaviour_"+functionName+"_used_keys = create_set({"+ string.Join(", " , usedkeys) + "})",
|
||||
"behaviour_" + functionName + "_used_keys = create_set({" + string.Join(", ", usedkeys) + "})",
|
||||
"--[[",
|
||||
description,
|
||||
"]]",
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace AspectedRouting.IO.itinero2
|
|||
|
||||
|
||||
var aspects = new List<string>();
|
||||
|
||||
var tags = new LuaLiteral(Typs.Tags, "tags");
|
||||
foreach (var (paramName, expr) in _profile.Priority)
|
||||
{
|
||||
var weightExpr = parameters[paramName].Evaluate(_context);
|
||||
|
@ -31,7 +31,7 @@ namespace AspectedRouting.IO.itinero2
|
|||
// The expression might still have multiple typings,
|
||||
// which take inputs different from 'Tags', so we specialize the expr first
|
||||
var appliedExpr = Funcs.Either(Funcs.Id, Funcs.Const, expr)
|
||||
.Apply(new LuaLiteral(Typs.Tags, "tags").SpecializeToSmallestType())
|
||||
.Apply(tags)
|
||||
.PruneTypes(tp => !(tp is Curry));
|
||||
var exprSpecialized = appliedExpr.Optimize(out _);
|
||||
|
||||
|
@ -48,7 +48,8 @@ namespace AspectedRouting.IO.itinero2
|
|||
aspects.Add(weight + " * " + exprInLua);
|
||||
}
|
||||
|
||||
Console.WriteLine(aspects.Lined());
|
||||
var scalingFactor = Funcs.Default.Apply(new Constant(Typs.Double, 1.0), _profile.ScalingFactor, tags)
|
||||
.SpecializeToSmallestType();
|
||||
var code = new List<string>
|
||||
{
|
||||
"--[[",
|
||||
|
@ -58,7 +59,10 @@ namespace AspectedRouting.IO.itinero2
|
|||
"function calculate_priority(parameters, tags, result, access, oneway, speed)",
|
||||
" local distance = 1",
|
||||
" local priority = \n " + string.Join(" +\n ", aspects),
|
||||
" return priority",
|
||||
"",
|
||||
"local scalingfactor",
|
||||
Snippets.Convert(_skeleton, "scalingfactor", scalingFactor),
|
||||
" return priority * scalingfactor",
|
||||
"end"
|
||||
};
|
||||
return code.Lined();
|
||||
|
|
|
@ -24,10 +24,10 @@ namespace AspectedRouting.IO.jsonParser
|
|||
return null;
|
||||
}
|
||||
|
||||
Console.Write("Parsing " + fileName+"... ");
|
||||
Console.Write("Parsing " + fileName + "... ");
|
||||
|
||||
var aspect = doc.RootElement.ParseAspect(fileName, c);
|
||||
|
||||
var aspect= doc.RootElement.ParseAspect(fileName, c);
|
||||
|
||||
Console.WriteLine($"\rAspect {aspect.Name} has type {string.Join(",", aspect.ExpressionImplementation.Types)}");
|
||||
return aspect;
|
||||
}
|
||||
|
@ -113,6 +113,7 @@ namespace AspectedRouting.IO.jsonParser
|
|||
var access = ParseProfileProperty(e, contextWithParameters, "access").Finalize();
|
||||
var oneway = ParseProfileProperty(e, contextWithParameters, "oneway").Finalize();
|
||||
var speed = ParseProfileProperty(e, contextWithParameters, "speed").Finalize();
|
||||
var scalingFactor = ParseProfileProperty(e, contextWithParameters, "scalingfactor", Funcs.Const.Apply(new Constant(1))).Finalize();
|
||||
var obstacle_access = ParseProfileProperty(e, contextWithParameters, "obstacleaccess", Funcs.Const.Apply(new Constant(new Var("any"), null))).Finalize();
|
||||
var obstacle_cost = ParseProfileProperty(e, contextWithParameters, "obstaclecost", Funcs.Const.Apply(new Constant(new Var("any0"), null))).Finalize();
|
||||
|
||||
|
@ -174,14 +175,15 @@ namespace AspectedRouting.IO.jsonParser
|
|||
speed,
|
||||
obstacle_access, obstacle_cost,
|
||||
weights,
|
||||
scalingFactor,
|
||||
metadata,
|
||||
lastChange
|
||||
);
|
||||
}
|
||||
|
||||
private static readonly IExpression _mconst = Funcs.EitherFunc.Apply( Funcs.Id, Funcs.Const);
|
||||
private static readonly IExpression _mconst = Funcs.EitherFunc.Apply(Funcs.Id, Funcs.Const);
|
||||
|
||||
private static readonly IExpression _mappingWrapper = Funcs.EitherFunc.Apply( Funcs.Id, Funcs.StringStringToTags);
|
||||
private static readonly IExpression _mappingWrapper = Funcs.EitherFunc.Apply(Funcs.Id, Funcs.StringStringToTags);
|
||||
|
||||
private static IExpression ParseMapping(IEnumerable<JsonProperty> allArgs, Context context)
|
||||
{
|
||||
|
@ -262,7 +264,7 @@ namespace AspectedRouting.IO.jsonParser
|
|||
var exprs = e.EnumerateArray().Select(json =>
|
||||
Funcs.Either(Funcs.Id, Funcs.Const, json.ParseExpression(context)))
|
||||
.ToList();
|
||||
|
||||
|
||||
var list = new Constant(exprs);
|
||||
return Funcs.Either(Funcs.Id, Funcs.ListDot, list);
|
||||
}
|
||||
|
@ -310,18 +312,19 @@ namespace AspectedRouting.IO.jsonParser
|
|||
{
|
||||
// This is a parameter, the type of it is free
|
||||
if (context.Parameters.TryGetValue(s.Substring(1), out var param))
|
||||
{
|
||||
{
|
||||
return new Parameter(s).Specialize(param.Types);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
return new Parameter(s);
|
||||
}
|
||||
|
||||
return new Constant(s);
|
||||
}
|
||||
|
||||
if (e.ValueKind == JsonValueKind.Null) {
|
||||
if (e.ValueKind == JsonValueKind.Null)
|
||||
{
|
||||
return new Constant(new Var("a"), null);
|
||||
}
|
||||
|
||||
|
@ -375,7 +378,7 @@ namespace AspectedRouting.IO.jsonParser
|
|||
|
||||
|
||||
foreach (var argName in func.ArgNames.GetRange(1, func.ArgNames.Count - 1))
|
||||
// We skip the first argument, that one is already added
|
||||
// We skip the first argument, that one is already added
|
||||
{
|
||||
args.Add(allExprs[argName]);
|
||||
}
|
||||
|
@ -405,7 +408,7 @@ namespace AspectedRouting.IO.jsonParser
|
|||
if (!prop.Name.StartsWith("$")) continue;
|
||||
|
||||
|
||||
var f = (IExpression) Funcs.BuiltinByName(prop.Name);
|
||||
var f = (IExpression)Funcs.BuiltinByName(prop.Name);
|
||||
if (f == null || f.Types.Count() == 0)
|
||||
{
|
||||
throw new KeyNotFoundException($"The builtin function {prop.Name} was not found");
|
||||
|
@ -434,7 +437,7 @@ namespace AspectedRouting.IO.jsonParser
|
|||
// It gets an extra argument injected
|
||||
var neededKeys = fArg.PossibleTags().Keys.ToList();
|
||||
var neededKeysArg = new Constant(new ListType(Typs.String), neededKeys);
|
||||
f = f.Apply(new[] {neededKeysArg});
|
||||
f = f.Apply(new[] { neededKeysArg });
|
||||
}
|
||||
|
||||
var appliedDot = new Apply(new Apply(Funcs.Dot, f), fArg);
|
||||
|
@ -524,7 +527,7 @@ namespace AspectedRouting.IO.jsonParser
|
|||
$"filename is {filepath}, declared name is {name}");
|
||||
}
|
||||
|
||||
var keys = (IEnumerable<string>) expr.PossibleTags()?.Keys ?? new List<string>();
|
||||
var keys = (IEnumerable<string>)expr.PossibleTags()?.Keys ?? new List<string>();
|
||||
foreach (var key in keys)
|
||||
{
|
||||
if (!key.Trim().Equals(key))
|
||||
|
|
|
@ -34,6 +34,7 @@ namespace AspectedRouting.Language.Expression
|
|||
|
||||
public Dictionary<string, IExpression> Priority { get; }
|
||||
|
||||
public IExpression ScalingFactor { get; }
|
||||
|
||||
/**
|
||||
* Moment of last change of any upstream file
|
||||
|
@ -45,7 +46,7 @@ namespace AspectedRouting.Language.Expression
|
|||
Dictionary<string, Dictionary<string, IExpression>> behaviours,
|
||||
IExpression access, IExpression oneway, IExpression speed,
|
||||
IExpression obstacleAccess, IExpression obstacleCost,
|
||||
Dictionary<string, IExpression> priority, List<string> metadata, DateTime lastChange)
|
||||
Dictionary<string, IExpression> priority, IExpression scalingFactor, List<string> metadata, DateTime lastChange)
|
||||
{
|
||||
Name = name;
|
||||
Description = description;
|
||||
|
@ -58,6 +59,7 @@ namespace AspectedRouting.Language.Expression
|
|||
ObstacleAccess = obstacleAccess.Optimize(out _);
|
||||
ObstacleCost = obstacleCost.Optimize(out _);
|
||||
Priority = priority;
|
||||
ScalingFactor = scalingFactor;
|
||||
Metadata = metadata;
|
||||
LastChange = lastChange;
|
||||
DefaultParameters = defaultParameters;
|
||||
|
@ -74,7 +76,7 @@ namespace AspectedRouting.Language.Expression
|
|||
{
|
||||
if (e == null)
|
||||
{
|
||||
throw new Exception("No expression given for " +name);
|
||||
throw new Exception("No expression given for " + name);
|
||||
}
|
||||
if (e.Types.Count() == 1)
|
||||
{
|
||||
|
@ -91,7 +93,7 @@ namespace AspectedRouting.Language.Expression
|
|||
l.AddRange(DefaultParameters.Values);
|
||||
l.AddRange(Behaviours.Values.SelectMany(b => b.Values));
|
||||
l.AddRange(Priority.Values);
|
||||
|
||||
|
||||
|
||||
var allExpr = new List<IExpression>();
|
||||
allExpr.AddRange(l);
|
||||
|
@ -207,43 +209,18 @@ namespace AspectedRouting.Language.Expression
|
|||
}
|
||||
|
||||
|
||||
var aspectWeightObj = new Apply(
|
||||
var aspectWeight = new Apply(
|
||||
Funcs.EitherFunc.Apply(Funcs.Id, Funcs.Const, expression)
|
||||
, new Constant(tags)).Evaluate(c);
|
||||
, new Constant(tags)).EvaluateDouble(paramName, c);
|
||||
|
||||
double aspectWeight;
|
||||
switch (aspectWeightObj)
|
||||
{
|
||||
case bool b:
|
||||
aspectWeight = b ? 1.0 : 0.0;
|
||||
break;
|
||||
case double d:
|
||||
aspectWeight = d;
|
||||
break;
|
||||
case int j:
|
||||
aspectWeight = j;
|
||||
break;
|
||||
case string s:
|
||||
if (s.Equals("yes"))
|
||||
{
|
||||
aspectWeight = 1.0;
|
||||
break;
|
||||
}
|
||||
else if (s.Equals("no"))
|
||||
{
|
||||
aspectWeight = 0.0;
|
||||
break;
|
||||
}
|
||||
|
||||
throw new Exception($"Invalid value as result for {paramName}: got string {s}");
|
||||
default:
|
||||
throw new Exception($"Invalid value as result for {paramName}: got object {aspectWeightObj}");
|
||||
}
|
||||
|
||||
weightExplanation.Add($"({paramName} = {aspectInfluence}) * {aspectWeight}");
|
||||
priority += aspectInfluence * aspectWeight;
|
||||
}
|
||||
|
||||
var scalingFactor = Utils.AsDouble(ScalingFactor.Run(c, tags) ?? 1.0, "scalingfactor");
|
||||
weightExplanation.Add("Scaling factor: " + scalingFactor);
|
||||
priority *= scalingFactor;
|
||||
if (priority <= 0)
|
||||
{
|
||||
canAccess = "no";
|
||||
|
@ -257,7 +234,7 @@ namespace AspectedRouting.Language.Expression
|
|||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("CanAccess or oneway are not strings but " + canAccess.GetType().ToString() +
|
||||
throw new Exception("CanAccess or oneway are not strings but " + canAccess.GetType() +
|
||||
" and " + (oneway?.GetType()?.ToString() ?? "<null>"));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue