More typesystem fixes, atleast now properly works
This commit is contained in:
parent
173756818e
commit
57704f5ee5
21 changed files with 262 additions and 88 deletions
|
@ -329,11 +329,16 @@ namespace AspectedRouting.Test
|
|||
[Fact]
|
||||
public void SpecializeToCommonType()
|
||||
{
|
||||
var p0 = Funcs.Parse;
|
||||
var p1 = Funcs.Const.Apply(new Constant(1.0));
|
||||
var p0 = Funcs.Parse.Specialize(new Curry(Typs.String, Typs.PDouble));
|
||||
var p1 = Funcs.Const.Apply(new Constant(1.0)).Specialize(
|
||||
new Curry(new Var("a"), Typs.Double));
|
||||
|
||||
var exprs = new[] {p0, p1};
|
||||
var newTypes = exprs.SpecializeToCommonTypes(out var specializedExpressions);
|
||||
var newTypes = exprs.SpecializeToCommonTypes(out var _);
|
||||
Assert.Single( newTypes);
|
||||
|
||||
exprs = new[] {p1, p0};
|
||||
newTypes = exprs.SpecializeToCommonTypes(out var _);
|
||||
Assert.Single( newTypes);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace AspectedRouting.Test
|
|||
{"ferry", "yes"}
|
||||
};
|
||||
|
||||
Assert.Equal("tags -> double", string.Join(", ", aspect.Types));
|
||||
Assert.Equal("tags -> pdouble", string.Join(", ", aspect.Types));
|
||||
Assert.Equal(42d, new Apply(aspect, new Constant(tags)).Evaluate(null));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=af5d2251_002D713d_002D473f_002D9157_002D89c9d06216e5/@EntryIndexedValue"><SessionState ContinuousTestingIsOn="False" ContinuousTestingMode="0" FrameworkVersion="{x:Null}" IsLocked="False" Name="All tests from &lt;AspectedRouting.Test&gt;" PlatformMonoPreference="{x:Null}" PlatformType="{x:Null}" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=acd4e5d9_002D8d57_002D4495_002Da7aa_002D38598b9e98e0/@EntryIndexedValue"><SessionState ContinuousTestingIsOn="False" ContinuousTestingMode="0" FrameworkVersion="{x:Null}" IsLocked="False" Name="All tests from &lt;AspectedRouting.Test&gt;" PlatformMonoPreference="{x:Null}" PlatformType="{x:Null}" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<Project Location="/home/pietervdvn/werk/AspectedRouting/AspectedRouting.Test" Presentation="&lt;AspectedRouting.Test&gt;" />
|
||||
</SessionState></s:String>
|
||||
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=bad1d05d_002Df895_002D4e7d_002Da6e2_002Dede32f077b26/@EntryIndexedValue"><SessionState ContinuousTestingIsOn="False" ContinuousTestingMode="0" FrameworkVersion="{x:Null}" IsLocked="False" Name="SpecializeToCommonType" PlatformMonoPreference="{x:Null}" PlatformType="{x:Null}" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<TestAncestor>
|
||||
<TestId>xUnit::A1309041-8AAE-42D7-A886-94C9FFC6A28C::.NETCoreApp,Version=v3.1::AspectedRouting.Test.FunctionsTest.SpecializeToCommonType</TestId>
|
||||
</TestAncestor>
|
||||
</SessionState></s:String></wpf:ResourceDictionary>
|
|
@ -169,6 +169,7 @@ namespace AspectedRouting.IO.LuaSkeleton
|
|||
return called.Name;
|
||||
}
|
||||
|
||||
AddDependenciesFor(called);
|
||||
AddFunction(called);
|
||||
return $"{fc.CalledFunctionName.AsLuaIdentifier()}(parameters, tags, result)";
|
||||
case Constant c:
|
||||
|
|
|
@ -60,9 +60,8 @@ namespace AspectedRouting.IO.itinero1
|
|||
|
||||
|
||||
var exprInLua = _skeleton.ToLua(expression.Optimize());
|
||||
var subs = new Curry(Typs.Tags, new Var(("a"))).UnificationTable(expression.Types.First());
|
||||
if (subs != null && subs.TryGetValue("$a", out var resultType) &&
|
||||
(resultType.Equals(Typs.Bool) || resultType.Equals(Typs.String)))
|
||||
var resultTypes = expression.Types.Select(t => t.Uncurry().Last());
|
||||
if (resultTypes.Any(t => t.Name.Equals(Typs.Bool.Name)))
|
||||
{
|
||||
_skeleton. AddDep("parse");
|
||||
exprInLua = "parse(" + exprInLua + ")";
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
function atleast(minimumExpected, actual, thn, els)
|
||||
if (minimumExpected <= actual) then
|
||||
return thn;
|
||||
end
|
||||
return els
|
||||
end
|
|
@ -197,13 +197,8 @@ namespace AspectedRouting.Language
|
|||
|
||||
public static string TypeBreakdown(this IExpression e)
|
||||
{
|
||||
var text = "";
|
||||
e.Visit(x =>
|
||||
{
|
||||
text += $"\n\n{x}\n : {string.Join("\n : ", x.Types)}";
|
||||
return true;
|
||||
});
|
||||
return text;
|
||||
|
||||
return e.ToString() + " : "+string.Join(" ; ", e.Types);
|
||||
}
|
||||
|
||||
public static void SanityCheckProfile(this ProfileMetaData pmd, Context context)
|
||||
|
|
|
@ -83,14 +83,15 @@ namespace AspectedRouting.Language.Expression
|
|||
{
|
||||
try
|
||||
{
|
||||
_debugInfo = $"\n{f.Optimize().TypeBreakdown()}\n" +
|
||||
$"is applied on an argument with types:" +
|
||||
$"{string.Join(", ", argument.Optimize().Types)}";
|
||||
_debugInfo = $"\n{f.Optimize().TypeBreakdown().Indent()}\n" +
|
||||
$"is given the argument: " +
|
||||
"(" + argument.Optimize().TypeBreakdown() + ")";
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
_debugInfo = $"\n{f.TypeBreakdown()}\n" +
|
||||
$"{argument.TypeBreakdown()}";
|
||||
_debugInfo =$"\n (NO OPT) {f.TypeBreakdown().Indent()}\n" +
|
||||
$"is given the argument: " +
|
||||
"(" + argument.TypeBreakdown() + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -197,6 +198,7 @@ namespace AspectedRouting.Language.Expression
|
|||
|
||||
if (Types.Count() > 1)
|
||||
{
|
||||
// Too much types to optimize
|
||||
var optimized = new Dictionary<Type, (IExpression f, IExpression a)>();
|
||||
foreach (var (resultType, (f, a)) in FunctionApplications)
|
||||
{
|
||||
|
@ -209,6 +211,7 @@ namespace AspectedRouting.Language.Expression
|
|||
}
|
||||
|
||||
{
|
||||
// id a => a
|
||||
var arg = new List<IExpression>();
|
||||
if (
|
||||
Deconstruct.UnApplyAny(
|
||||
|
@ -220,6 +223,37 @@ namespace AspectedRouting.Language.Expression
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
// ifdotted fcondition fthen felse arg => if (fcondition arg) (fthen arg) (felse arg)
|
||||
var fcondition = new List<IExpression>();
|
||||
var fthen = new List<IExpression>();
|
||||
var felse = new List<IExpression>();
|
||||
var arg = new List<IExpression>();
|
||||
|
||||
if (
|
||||
Deconstruct.UnApplyAny(
|
||||
Deconstruct.UnApply(
|
||||
Deconstruct.UnApply(
|
||||
Deconstruct.UnApply(
|
||||
Deconstruct.IsFunc(Funcs.IfDotted),
|
||||
Deconstruct.Assign(fcondition)),
|
||||
Deconstruct.Assign(fthen)),
|
||||
Deconstruct.Assign(felse)),
|
||||
Deconstruct.Assign(arg)
|
||||
).Invoke(this))
|
||||
{
|
||||
var a = arg.First();
|
||||
return
|
||||
Funcs.If.Apply(
|
||||
fcondition.First().Apply(a),
|
||||
fthen.First().Apply(a),
|
||||
felse.First().Apply(a)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
var (f, a) = FunctionApplications.Values.First();
|
||||
|
||||
|
|
|
@ -158,6 +158,11 @@ namespace AspectedRouting.Language.Expression
|
|||
priority += aspectInfluence * aspectWeight;
|
||||
}
|
||||
|
||||
if (priority <= 0)
|
||||
{
|
||||
canAccess = "no";
|
||||
}
|
||||
|
||||
return new ProfileResult((string) canAccess, (string) oneway, speed, priority,
|
||||
string.Join("\n ", weightExplanation));
|
||||
}
|
||||
|
|
|
@ -45,18 +45,27 @@ namespace AspectedRouting.Language.Functions
|
|||
public override object Evaluate(Context c, params IExpression[] arguments)
|
||||
{
|
||||
var minimum = arguments[0].Evaluate(c);
|
||||
var f = (IExpression) arguments[1].Evaluate(c);
|
||||
var then = arguments[2].Evaluate(c);
|
||||
var @else = arguments[3].Evaluate(c);
|
||||
var x = arguments[4];
|
||||
|
||||
var arg1 = f.Evaluate(c, x);
|
||||
var arg1 = arguments[1].Evaluate(c, x);
|
||||
|
||||
if (minimum == null || arg1 == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (minimum is IExpression e)
|
||||
{
|
||||
minimum = e.Evaluate(c);
|
||||
}
|
||||
|
||||
if (arg1 is IExpression e1)
|
||||
{
|
||||
arg1 = e1.Evaluate(c);
|
||||
}
|
||||
|
||||
if (minimum is int i0)
|
||||
{
|
||||
minimum = (double) i0;
|
||||
|
|
|
@ -18,6 +18,10 @@ namespace AspectedRouting.Language.Functions
|
|||
if (o is IEnumerable<IExpression> enumerable)
|
||||
{
|
||||
o = enumerable.ToList();
|
||||
if (enumerable.Any(x => x == null))
|
||||
{
|
||||
throw new NullReferenceException("Some subexpression is null");
|
||||
}
|
||||
}
|
||||
|
||||
_o = o;
|
||||
|
@ -29,6 +33,10 @@ namespace AspectedRouting.Language.Functions
|
|||
if (o is IEnumerable<IExpression> enumerable)
|
||||
{
|
||||
o = enumerable.ToList();
|
||||
if (enumerable.Any(x => x == null))
|
||||
{
|
||||
throw new NullReferenceException("Some subexpression is null");
|
||||
}
|
||||
}
|
||||
|
||||
_o = o;
|
||||
|
@ -39,6 +47,10 @@ namespace AspectedRouting.Language.Functions
|
|||
var tps = exprs
|
||||
.SpecializeToCommonTypes(out var specializedVersions)
|
||||
.Select(t => new ListType(t));
|
||||
if(specializedVersions.Any(x => x == null))
|
||||
{
|
||||
throw new Exception("Specializing to common types failed for "+string.Join("," ,exprs.Select(e => e.ToString())));
|
||||
}
|
||||
Types = tps.ToList();
|
||||
_o = specializedVersions;
|
||||
}
|
||||
|
@ -49,6 +61,10 @@ namespace AspectedRouting.Language.Functions
|
|||
{
|
||||
Types = exprs
|
||||
.SpecializeToCommonTypes(out var specializedVersions).Select(t => new ListType(t)).ToList();
|
||||
if (specializedVersions.Any(x => x == null))
|
||||
{
|
||||
throw new NullReferenceException("Some subexpression is null");
|
||||
}
|
||||
_o = specializedVersions.ToList();
|
||||
}
|
||||
catch (Exception e)
|
||||
|
|
|
@ -8,7 +8,8 @@ namespace AspectedRouting.Language.Functions
|
|||
{
|
||||
public class Dot : Function
|
||||
{
|
||||
public override string Description { get; } = "Higher order function: converts `f (g a)` into `(dot f g) a`. In other words, this fuses `f` and `g` in a new function, which allows the argument to be lifted out of the expression ";
|
||||
public override string Description { get; } =
|
||||
"Higher order function: converts `f (g a)` into `(dot f g) a`. In other words, this fuses `f` and `g` in a new function, which allows the argument to be lifted out of the expression ";
|
||||
|
||||
public override List<string> ArgNames { get; } = new List<string> {"f", "g", "a"};
|
||||
public static readonly Var A = new Var("a");
|
||||
|
@ -33,6 +34,10 @@ namespace AspectedRouting.Language.Functions
|
|||
|
||||
public override object Evaluate(Context c, params IExpression[] arguments)
|
||||
{
|
||||
if (arguments.Count() <= 2)
|
||||
{
|
||||
}
|
||||
|
||||
var f0 = arguments[0];
|
||||
var f1 = arguments[1];
|
||||
var resultType = ((Curry) f1.Types.First()).ResultType;
|
||||
|
|
|
@ -39,7 +39,6 @@ namespace AspectedRouting.Language
|
|||
/// <param name="argument"></param>
|
||||
/// <returns></returns>
|
||||
// IExpression OptimizeWithArgument(IExpression argument);
|
||||
|
||||
void Visit(Func<IExpression, bool> f);
|
||||
}
|
||||
|
||||
|
@ -101,8 +100,11 @@ namespace AspectedRouting.Language
|
|||
out IEnumerable<Type> specializedTypes, out IEnumerable<IExpression> specializedExpressions)
|
||||
{
|
||||
specializedTypes = null;
|
||||
var expressions = exprs.ToList();
|
||||
foreach (var f in expressions)
|
||||
var exprsForTypes = exprs.SortWidestToSmallest();
|
||||
exprsForTypes.Reverse();
|
||||
|
||||
|
||||
foreach (var f in exprsForTypes)
|
||||
{
|
||||
if (specializedTypes == null)
|
||||
{
|
||||
|
@ -110,9 +112,7 @@ namespace AspectedRouting.Language
|
|||
continue;
|
||||
}
|
||||
|
||||
// TODO FIXME
|
||||
// EITHER THE TYPES HAVE TO BE FROM SPECIFIC TO NON-SPECIFIC ORDER OR VICE VERSA
|
||||
var specialized = f.Types.RenameVars(specializedTypes).SpecializeTo(specializedTypes);
|
||||
var specialized = f.Types.RenameVars(specializedTypes).SpecializeTo(specializedTypes, false);
|
||||
// ReSharper disable once JoinNullCheckWithUsage
|
||||
if (specialized == null)
|
||||
{
|
||||
|
@ -126,7 +126,15 @@ namespace AspectedRouting.Language
|
|||
}
|
||||
|
||||
var tps = specializedTypes;
|
||||
return specializedExpressions = expressions.Select(expr => expr.Specialize(tps));
|
||||
|
||||
var optExprs = new List<IExpression>();
|
||||
foreach (var expr in exprs)
|
||||
{
|
||||
var exprOpt = expr.Specialize(tps);
|
||||
optExprs.Add(exprOpt);
|
||||
}
|
||||
|
||||
return specializedExpressions = optExprs;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
|
@ -23,7 +24,7 @@ namespace AspectedRouting.Language.Typ
|
|||
}
|
||||
|
||||
|
||||
public static HashSet<Type> SpecializeTo(this IEnumerable<Type> types0, IEnumerable<Type> allowedTypes)
|
||||
public static HashSet<Type> SpecializeTo(this IEnumerable<Type> types0, IEnumerable<Type> allowedTypes, bool reverseSuperSet = true)
|
||||
{
|
||||
var results = new HashSet<Type>();
|
||||
|
||||
|
@ -32,7 +33,7 @@ namespace AspectedRouting.Language.Typ
|
|||
{
|
||||
foreach (var allowed in allowedTypes)
|
||||
{
|
||||
var unified = t0.Unify(allowed, true);
|
||||
var unified = t0.Unify(allowed, reverseSuperSet);
|
||||
if (unified != null)
|
||||
{
|
||||
results.Add(unified);
|
||||
|
@ -70,6 +71,7 @@ namespace AspectedRouting.Language.Typ
|
|||
{
|
||||
return SelectSmallestUnion(t1, subbed);
|
||||
}
|
||||
|
||||
return SelectSmallestUnion(subbed, t1);
|
||||
}
|
||||
|
||||
|
@ -99,6 +101,81 @@ namespace AspectedRouting.Language.Typ
|
|||
}
|
||||
}
|
||||
|
||||
public static List<IExpression> SortWidestToSmallest(this IEnumerable<IExpression> expressions)
|
||||
{
|
||||
var all = expressions.ToHashSet();
|
||||
var sorted = new List<IExpression>();
|
||||
while (all.Any())
|
||||
{
|
||||
var widest = SelectWidestType(all);
|
||||
if (widest == null)
|
||||
{
|
||||
throw new ArgumentException("Can not sort widest to smallest");
|
||||
}
|
||||
all.Remove(widest);
|
||||
sorted.Add(widest);
|
||||
}
|
||||
|
||||
return sorted;
|
||||
}
|
||||
|
||||
public static IExpression SelectSmallestType(IEnumerable<IExpression> expressions)
|
||||
{
|
||||
IExpression smallest = null;
|
||||
foreach (var current in expressions)
|
||||
{
|
||||
if (smallest == null)
|
||||
{
|
||||
smallest = current;
|
||||
continue;
|
||||
}
|
||||
if (smallest.Types.AllAreSuperset(current.Types))
|
||||
{
|
||||
smallest = current;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return smallest;
|
||||
}
|
||||
|
||||
public static IExpression SelectWidestType(IEnumerable<IExpression> expressions)
|
||||
{
|
||||
IExpression widest = null;
|
||||
foreach (var current in expressions)
|
||||
{
|
||||
if (widest == null)
|
||||
{
|
||||
widest = current;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (current.Types.AllAreSuperset(widest.Types))
|
||||
{
|
||||
widest = current;
|
||||
}
|
||||
}
|
||||
|
||||
return widest;
|
||||
}
|
||||
|
||||
public static bool AllAreSuperset(this IEnumerable<Type> shouldBeSuper, IEnumerable<Type> shouldBeSmaller)
|
||||
{
|
||||
foreach (var super in shouldBeSuper)
|
||||
{
|
||||
foreach (var smaller in shouldBeSmaller)
|
||||
{
|
||||
if (!super.IsSuperSet(smaller))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to unify t0 with all t1's.
|
||||
/// Every match is returned
|
||||
|
@ -136,7 +213,6 @@ namespace AspectedRouting.Language.Typ
|
|||
}
|
||||
|
||||
|
||||
|
||||
public static Type Substitute(this Type t0, Dictionary<string, Type> substitutions)
|
||||
{
|
||||
switch (t0)
|
||||
|
@ -161,7 +237,8 @@ namespace AspectedRouting.Language.Typ
|
|||
/// <param name="t0"></param>
|
||||
/// <param name="t1"></param>
|
||||
/// <returns></returns>
|
||||
public static Dictionary<string, Type> UnificationTable(this Type t0, Type t1, bool reverseSupersetRelation = false)
|
||||
public static Dictionary<string, Type> UnificationTable(this Type t0, Type t1,
|
||||
bool reverseSupersetRelation = false)
|
||||
{
|
||||
var substitutionsOn0 = new Dictionary<string, Type>();
|
||||
|
||||
|
@ -281,6 +358,11 @@ namespace AspectedRouting.Language.Typ
|
|||
|
||||
public static bool IsSuperSet(this Type t0, Type t1)
|
||||
{
|
||||
if (t0 is Var || t1 is Var)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (t0)
|
||||
{
|
||||
case StringType _ when t1 is BoolType _:
|
||||
|
|
|
@ -63,11 +63,6 @@ namespace AspectedRouting
|
|||
var result = new List<(ProfileMetaData profile, List<BehaviourTestSuite> profileTests)>();
|
||||
foreach (var jsonFile in jsonFiles)
|
||||
{
|
||||
if (!jsonFile.Contains("bicycle"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var profile =
|
||||
|
@ -227,6 +222,7 @@ namespace AspectedRouting
|
|||
|
||||
|
||||
// With everything parsed and typechecked, time for tests
|
||||
var testsOk = true;
|
||||
foreach (var (aspect, t) in aspects)
|
||||
{
|
||||
if (t == null)
|
||||
|
@ -235,18 +231,27 @@ namespace AspectedRouting
|
|||
}
|
||||
else
|
||||
{
|
||||
t.Run();
|
||||
testsOk &= t.Run();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
foreach (var (profile, profileTests) in profiles)
|
||||
{
|
||||
foreach (var test in profileTests)
|
||||
{
|
||||
test.Run(context);
|
||||
testsOk &= test.Run(context);
|
||||
}
|
||||
}
|
||||
|
||||
if (!testsOk)
|
||||
{
|
||||
Console.WriteLine("Some tests failed, quitting now without generating output");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var (profile, profileTests) in profiles)
|
||||
{
|
||||
PrintUsedTags(profile, context);
|
||||
|
||||
var aspectTests = aspects.Select(a => a.tests).ToList();
|
||||
|
|
|
@ -61,7 +61,7 @@ namespace AspectedRouting.Tests
|
|||
|
||||
|
||||
|
||||
public void Run()
|
||||
public bool Run()
|
||||
{
|
||||
var failed = false;
|
||||
var testCase = 0;
|
||||
|
@ -88,12 +88,9 @@ namespace AspectedRouting.Tests
|
|||
}
|
||||
}
|
||||
|
||||
if (failed)
|
||||
{
|
||||
throw new ArgumentException("Some test failed");
|
||||
}
|
||||
|
||||
Console.WriteLine($"[{FunctionToApply.Name}] {testCase} tests successful");
|
||||
Console.WriteLine($"[{FunctionToApply.Name}] {testCase} tests " + (failed ? "failed" : "successful"));
|
||||
return !failed;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -78,7 +78,6 @@ namespace AspectedRouting.Tests
|
|||
}
|
||||
|
||||
|
||||
|
||||
var expected = new ProfileResult(
|
||||
testData[0],
|
||||
testData[1],
|
||||
|
@ -88,7 +87,8 @@ namespace AspectedRouting.Tests
|
|||
|
||||
if (expected.Priority == 0 && expected.Access != "no")
|
||||
{
|
||||
throw new ArgumentException("A priority of zero is interpreted as 'no access' - don't use it");
|
||||
throw new ArgumentException(
|
||||
"A priority of zero is interpreted as 'no access' - don't use it");
|
||||
}
|
||||
|
||||
var vals = testData.GetRange(4, testData.Count - 4);
|
||||
|
@ -192,11 +192,8 @@ namespace AspectedRouting.Tests
|
|||
return success;
|
||||
}
|
||||
|
||||
public void Run(Context c)
|
||||
|
||||
public bool Run(Context c)
|
||||
{
|
||||
|
||||
|
||||
var allOk = true;
|
||||
var i = 1;
|
||||
foreach (var (expected, tags) in Tests)
|
||||
|
@ -213,14 +210,9 @@ namespace AspectedRouting.Tests
|
|||
i++;
|
||||
}
|
||||
|
||||
if (!allOk)
|
||||
{
|
||||
throw new ArgumentException("Some tests failed for " + BehaviourName);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"[{Profile.Name}] {Tests.Count()} tests successful for behaviour {BehaviourName}");
|
||||
}
|
||||
Console.WriteLine($"[{Profile.Name}] {Tests.Count()} tests " + (allOk ? "successfull" : "executed, some failed") +
|
||||
$" for behaviour {BehaviourName}");
|
||||
return allOk;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -39,7 +39,17 @@
|
|||
"#timeNeeded": "$speed",
|
||||
"#distance": "$distance",
|
||||
"#trespassingPenalty": "$clean_permission_score",
|
||||
"#leastSafetyPenalty": 0
|
||||
"#leastSafetyPenalty": {
|
||||
"$multiply": [
|
||||
"$speed",
|
||||
{
|
||||
"$atleast": "#leastSafetyRequired",
|
||||
"f": "$bicycle.safety",
|
||||
"then": 0,
|
||||
"else": -1
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"defaults": {
|
||||
"#defaultSpeed": 15,
|
||||
|
@ -56,16 +66,18 @@
|
|||
"#trespassingPenalty": 15,
|
||||
"#": "This is not a priority weight, but rather a kind of access restriction. If 'leastafety' is not met, a huge penalty is applied, namely #leastSafetyPenalty. Note: 0.1 is the safety level of a primary without cycle highway",
|
||||
"#leastSafetyRequired": 0.11,
|
||||
"#leastSafetyPenalty": 2
|
||||
"#leastSafetyPenalty": 0
|
||||
},
|
||||
"behaviours": {
|
||||
"fastest": {
|
||||
"description": "The fastest route to your destination",
|
||||
"#timeNeeded": 1
|
||||
"#timeNeeded": 1,
|
||||
"#leastSafetyPenalty": 2
|
||||
},
|
||||
"shortest": {
|
||||
"description": "The shortest route, independent of of speed",
|
||||
"#distance": 1
|
||||
"#distance": 1,
|
||||
"#leastSafetyPenalty": 2
|
||||
},
|
||||
"safety": {
|
||||
"description": "A defensive route shying away from big roads with lots of cars",
|
||||
|
@ -73,7 +85,8 @@
|
|||
},
|
||||
"comfort": {
|
||||
"description": "A comfortable route preferring well-paved roads, smaller roads and a bit of scenery at the cost of speed",
|
||||
"#comfort": 1
|
||||
"#comfort": 1,
|
||||
"#leastSafetyPenalty": 2
|
||||
},
|
||||
"comfort_safety": {
|
||||
"description": "A route which aims to be both safe and comfortable at the cost of speed",
|
||||
|
@ -84,7 +97,8 @@
|
|||
"description": "A profile for a bike with an electrical motor where the engine doesn't go faster then 25km/h (thus NOT the speed-pedelec). This is a variation of the normal fastest, but with a faster default speed. As the maxspeed is 30, it'll resemble shortest a bit more on 'normal' streets and will penalize slower roads more",
|
||||
"#defaultSpeed": 23,
|
||||
"#maxspeed": 30,
|
||||
"#timeNeeded": 1
|
||||
"#timeNeeded": 1,
|
||||
"#leastSafetyPenalty": 2
|
||||
},
|
||||
"networks": {
|
||||
"description": "A recreative route following any existing cycling network. Might make a few detours",
|
||||
|
@ -111,7 +125,8 @@
|
|||
"cycle_highway": {
|
||||
"description": "A route preferring the 'cycle-highways'. On non-cycleways, fastest is used (with a very low factor) in order to make sure the behaviour there is defined ",
|
||||
"#cycleHighwayNetworkScore": 20,
|
||||
"#timeNeeded": 0.1
|
||||
"#timeNeeded": 0.1,
|
||||
"#leastSafetyPenalty": 2
|
||||
},
|
||||
"node_network": {
|
||||
"description": "A route following the recreational node network. Might make detours",
|
||||
|
|
|
@ -27,9 +27,14 @@
|
|||
"speed":{
|
||||
"$min":
|
||||
[
|
||||
{"$multiply":["#defaultSpeed", "$bicycle.speed_factor"]},
|
||||
"#maxspeed",
|
||||
"$legal_maxspeed_be",
|
||||
"#maxspeed"
|
||||
{
|
||||
"$multiply": [
|
||||
"#defaultSpeed",
|
||||
"$bicycle.speed_factor"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"access":"$speedPedelec.access_be",
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
access,oneway,speed,priority,highway,bicycle,surface,cycleway:left,oneway,oneway:bicycle,access,maxspeed,junction
|
||||
no,both,0,0,,,,,,,,,
|
||||
designated,both,15,15,cycleway,,,,,,,,
|
||||
yes,both,15,15,primary,,,,,,,,
|
||||
yes,both,15,15,primary,yes,,,,,,,
|
||||
no,both,15,-15,primary,,,,,,,,
|
||||
no,both,15,-15,primary,yes,,,,,,,
|
||||
yes,both,15,15,residential,,,,,,,,
|
||||
yes,both,13.5,13.5,residential,yes,sett,,,,,,
|
||||
dismount,both,2.25,2.25,pedestrian,,,,,,,,
|
||||
|
|
|
|
@ -2,4 +2,4 @@ access,oneway,speed,priority,highway,surface
|
|||
no,both,0,0,,
|
||||
designated,both,15,1,cycleway,
|
||||
yes,both,5.25,1,path,ground
|
||||
yes,both,15,1,primary,
|
||||
no,both,15,-29,primary,
|
||||
|
|
|
Loading…
Add table
Add a link
Reference in a new issue