diff --git a/AspectedRouting.Test/FunctionsTest.cs b/AspectedRouting.Test/FunctionsTest.cs index 955b8dd..8f32bd2 100644 --- a/AspectedRouting.Test/FunctionsTest.cs +++ b/AspectedRouting.Test/FunctionsTest.cs @@ -322,9 +322,19 @@ namespace AspectedRouting.Test new Curry(Typs.String, Typs.String)); var f1 = f.Specialize(strstrstr); - - Assert.Equal(new[] {strstrb, strstrstr}, f1.Types); + Assert.Equal(new[] {strstrb, strstrstr}, f1.Types); + } + + [Fact] + public void SpecializeToCommonType() + { + var p0 = Funcs.Parse; + var p1 = Funcs.Const.Apply(new Constant(1.0)); + + var exprs = new[] {p0, p1}; + var newTypes = exprs.SpecializeToCommonTypes(out var specializedExpressions); + Assert.Single(newTypes); } } } \ No newline at end of file diff --git a/AspectedRouting.Test/TestAnalysis.cs b/AspectedRouting.Test/TestAnalysis.cs deleted file mode 100644 index 7996dd5..0000000 --- a/AspectedRouting.Test/TestAnalysis.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using AspectedRouting.Language; -using AspectedRouting.Language.Functions; -using Xunit; - -namespace AspectedRouting.Test -{ - public class TestAnalysis - { - - } -} \ No newline at end of file diff --git a/AspectedRouting.sln.DotSettings.user b/AspectedRouting.sln.DotSettings.user new file mode 100644 index 0000000..4fccd45 --- /dev/null +++ b/AspectedRouting.sln.DotSettings.user @@ -0,0 +1,9 @@ + + <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> + <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> \ No newline at end of file diff --git a/AspectedRouting/IO/LuaSkeleton/LuaParameterPrinter.Parameters.cs b/AspectedRouting/IO/LuaSkeleton/LuaParameterPrinter.Parameters.cs index cc2db70..7dfc538 100644 --- a/AspectedRouting/IO/LuaSkeleton/LuaParameterPrinter.Parameters.cs +++ b/AspectedRouting/IO/LuaSkeleton/LuaParameterPrinter.Parameters.cs @@ -27,7 +27,7 @@ namespace AspectedRouting.IO.itinero1 "end" }; - return string.Join("\n",impl); + return string.Join("\n", impl); } /// @@ -56,7 +56,11 @@ namespace AspectedRouting.IO.itinero1 continue; } - impl += $" parameters.{paramName.TrimStart('#').AsLuaIdentifier()} = {_skeleton.ToLua(value)}\n"; + var paramNameTrimmed = paramName.TrimStart('#').AsLuaIdentifier(); + if (!string.IsNullOrEmpty(paramNameTrimmed)) + { + impl += $" parameters.{paramNameTrimmed} = {_skeleton.ToLua(value)}\n"; + } } return impl; diff --git a/AspectedRouting/IO/lua/asNumber.lua b/AspectedRouting/IO/lua/asNumber.lua index 1669e7a..caff104 100644 --- a/AspectedRouting/IO/lua/asNumber.lua +++ b/AspectedRouting/IO/lua/asNumber.lua @@ -1,4 +1,7 @@ -function as_number(a) - +function atleast(a, b) + if(a <= b) then + return "yes" + end + return "no" end \ No newline at end of file diff --git a/AspectedRouting/IO/lua/atleast.lua b/AspectedRouting/IO/lua/atleast.lua new file mode 100644 index 0000000..e69de29 diff --git a/AspectedRouting/IO/lua/unitTestProfile.lua b/AspectedRouting/IO/lua/unitTestProfile.lua index 7d7e39b..d312e6e 100644 --- a/AspectedRouting/IO/lua/unitTestProfile.lua +++ b/AspectedRouting/IO/lua/unitTestProfile.lua @@ -30,7 +30,13 @@ function unit_test_profile(profile_function, profile_name, index, expected, tags end - local actualOneway = result.direction; + local actualOneway = result.direction + + if(actualOneway == nil) then + print("Fail: result.direction is nil") + profile_failed = true; + end + if (result.direction == 0) then actualOneway = "both" elseif (result.direction == 1) then @@ -40,7 +46,7 @@ function unit_test_profile(profile_function, profile_name, index, expected, tags end if (expected.oneway ~= actualOneway) then - print("Test " .. tostring(index) .. " failed for " .. profile_name .. ".oneway: expected " .. expected.direction .. " but got " .. actualOneway) + print("Test " .. tostring(index) .. " failed for " .. profile_name .. ".oneway: expected " .. expected.oneway .. " but got " .. actualOneway) failed_profile_tests = true profile_failed = true end diff --git a/AspectedRouting/Language/Analysis.cs b/AspectedRouting/Language/Analysis.cs index 5d600ef..008442b 100644 --- a/AspectedRouting/Language/Analysis.cs +++ b/AspectedRouting/Language/Analysis.cs @@ -237,7 +237,7 @@ namespace AspectedRouting.Language var unused = defaultParameters.Except(usedParameters); if (unused.Any()) { - throw new ArgumentException("A default value is set for parameter, but it is unused: " + + Console.WriteLine("[WARNING] A default value is set for parameter, but it is unused: " + string.Join(", ", unused)); } diff --git a/AspectedRouting/Language/Funcs.cs b/AspectedRouting/Language/Funcs.cs index e6b5933..742340b 100644 --- a/AspectedRouting/Language/Funcs.cs +++ b/AspectedRouting/Language/Funcs.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Linq; using AspectedRouting.Language.Expression; @@ -32,6 +33,7 @@ namespace AspectedRouting.Language public static readonly Function Multiply = new Multiply(); + public static readonly Function AtLeast = new AtLeast(); public static readonly Function FirstOf = new FirstMatchOf(); public static readonly Function MustMatch = new MustMatch(); @@ -79,13 +81,35 @@ namespace AspectedRouting.Language return null; } - e = e.SpecializeToSmallestType(); + if (e.Types.Count() == 0) + { + throw new Exception("Expression has no valid types:\n" + e); + } + + var eSmallest = e.SpecializeToSmallestType(); + if (eSmallest == null || eSmallest.Types.Count() == 0) + { + throw new Exception("Could not specialize " + e); + } + // TODO FIX THIS so that it works // An argument 'optimizes' it's types from 'string -> bool' to 'string -> string' - e = e.Optimize(); - // - e.SanityCheck(); - return e; + try + { + var eOpt = eSmallest.Optimize(); if (eOpt == null || eOpt.Types.Count() == 0) + { + throw new Exception("Could not optimize " + eSmallest); + } + eOpt.SanityCheck(); + return eOpt; + } + catch + { + Console.WriteLine("Optimalization failed for "+eSmallest); + return eSmallest; + } + + } public static IExpression SpecializeToSmallestType(this IExpression e) diff --git a/AspectedRouting/Language/Functions/AtLeast.cs b/AspectedRouting/Language/Functions/AtLeast.cs new file mode 100644 index 0000000..5e1c683 --- /dev/null +++ b/AspectedRouting/Language/Functions/AtLeast.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using AspectedRouting.Language.Expression; +using AspectedRouting.Language.Typ; +using Type = AspectedRouting.Language.Typ.Type; + +namespace AspectedRouting.Language.Functions +{ + public class AtLeast : Function + { + public override string Description { get; } = + "Returns 'yes' if the second argument is bigger then the first argument. (Works great in combination with $dot)"; + + public override List ArgNames { get; } = new List {"minimum", "f", "then","else"}; + + private static Type a = new Var("a"); + private static Type b = new Var("b"); + + public AtLeast() : base("atleast", true, + new[] + { + Curry.ConstructFrom(a, + Typs.Double, + new Curry(b,Typs.Double), + a, a, b), + }) + { + } + + private AtLeast(IEnumerable types) : base("atleast", types) + { + } + + public override IExpression Specialize(IEnumerable allowedTypes) + { + var unified = Types.SpecializeTo(allowedTypes); + if (unified == null) + { + return null; + } + + return new AtLeast(unified); + } + + 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); + + if (minimum == null || arg1 == null) + { + return null; + } + + if (minimum is int i0) + { + minimum = (double) i0; + } + + if (arg1 is int i1) + { + arg1 = (double) i1; + } + + if (minimum is double d0 && arg1 is double d1) + { + if (d0 <= d1) + { + return then; + } + + return @else; + } + + throw new InvalidCastException("One of the arguments is not a number: "+minimum+", "+arg1); + + } + } +} \ No newline at end of file diff --git a/Profiles/bicycle/aspects/bicycle.legal_access.json b/Profiles/bicycle/aspects/bicycle.legal_access.json index 9eafc18..415b5d0 100644 --- a/Profiles/bicycle/aspects/bicycle.legal_access.json +++ b/Profiles/bicycle/aspects/bicycle.legal_access.json @@ -39,8 +39,8 @@ "pedestrian": "dismount", "corridor": "dismount", "path": "yes", - "primary": "no", - "primary_link": "no", + "primary": "yes", + "primary_link": "yes", "secondary": "yes", "secondary_link": "yes", "tertiary": "yes", diff --git a/Profiles/bicycle/aspects/bicycle.safety.json b/Profiles/bicycle/aspects/bicycle.safety.json index 5ccf4f6..241f033 100644 --- a/Profiles/bicycle/aspects/bicycle.safety.json +++ b/Profiles/bicycle/aspects/bicycle.safety.json @@ -9,7 +9,7 @@ "#": "access=no and access 'destination' implies this access for cars too and is a bonus!", "no": 1.5, "destination": 1.4, - "dismount": 0.01, + "dismount": 0.2, "designated": 1.5 }, "motor_vehicle": { @@ -33,7 +33,7 @@ }, "highway": { "cycleway": 1.0, - "primary": 0.3, + "primary": 0.1, "secondary": 0.4, "tertiary": 0.5, "unclassified": 0.8, @@ -44,31 +44,28 @@ "path": 0.9 }, "cycleway": { - "yes": 0.95, - "#": "TODO: the implied value for quite a bit of roads (residential, unclassified) is 'no', so this is a bit weird", - "no": 0.5, - "lane": 1, - "shared": 0.8, - "shared_lane": 0.8, - "share_busway": 0.9, + "#": "A distinct cycleway _always_ makes the road safer for cyclists, even if it is but a small lane. The default assumption is 'no', no cycleway, in which case the safety feeling is not improved", + "yes": 1.15, + "lane": 1.15, + "shared": 1.03, + "shared_lane": 1.03, + "share_busway": 1.05, "track": 1.5 }, "cycleway:left": { - "yes": 0.95, - "no": 0.5, - "lane": 1, - "shared": 0.8, - "shared_lane": 0.8, - "share_busway": 0.9, + "yes": 1.15, + "lane": 1.15, + "shared": 1.03, + "shared_lane": 1.03, + "share_busway": 1.05, "track": 1.5 }, "cycleway:right": { - "yes": 0.95, - "no": 0.5, - "lane": 1, - "shared": 0.8, - "shared_lane": 0.8, - "share_busway": 0.9, + "yes": 1.15, + "lane": 1.15, + "shared": 1.03, + "shared_lane": 1.03, + "share_busway": 1.05, "track": 1.5 } } diff --git a/Profiles/bicycle/bicycle.json b/Profiles/bicycle/bicycle.json index 62fdebe..117e143 100644 --- a/Profiles/bicycle/bicycle.json +++ b/Profiles/bicycle/bicycle.json @@ -15,15 +15,7 @@ "status", "network" ], - "access": { - "$ifDotted": { - "$dot": {"$notEq": "no"}, - "f": "$bicycle.legal_access" - }, - - "then": "$bicycle.legal_access", - "else": "$bicycle.network_is_bicycle_network" - }, + "access": "$bicycle.legal_access", "oneway": "$bicycle.oneway", "speed": { "$min": [ @@ -46,7 +38,8 @@ "#bicycleNetworkScore": "$bicycle.network_is_bicycle_network", "#timeNeeded": "$speed", "#distance": "$distance", - "#trespassingPenalty":"$clean_permission_score" + "#trespassingPenalty": "$clean_permission_score", + "#leastSafetyPenalty": 0 }, "defaults": { "#defaultSpeed": 15, @@ -60,7 +53,10 @@ "#cycleHighwayNetworkScore": 0, "#nodeNetworkScore": 0, "#bicycleNetworkScore": 0, - "#trespassingPenalty": 15 + "#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 }, "behaviours": { "fastest": { diff --git a/Profiles/bicycle/tests/bicycle.fastest.behaviour_test.csv b/Profiles/bicycle/tests/bicycle.fastest.behaviour_test.csv index 356af19..e7bdb6a 100644 --- a/Profiles/bicycle/tests/bicycle.fastest.behaviour_test.csv +++ b/Profiles/bicycle/tests/bicycle.fastest.behaviour_test.csv @@ -1,7 +1,7 @@ access,oneway,speed,priority,highway,bicycle,surface,cycleway:left,oneway,oneway:bicycle,access,maxspeed,junction no,both,0,0,,,,,,,,, designated,both,15,15,cycleway,,,,,,,, -no,both,0,0,primary,,,,,,,, +yes,both,15,15,primary,,,,,,,, yes,both,15,15,primary,yes,,,,,,, yes,both,15,15,residential,,,,,,,, yes,both,13.5,13.5,residential,yes,sett,,,,,, diff --git a/Profiles/bicycle/tests/bicycle.legal_access.test.csv b/Profiles/bicycle/tests/bicycle.legal_access.test.csv index f6be105..646a21b 100644 --- a/Profiles/bicycle/tests/bicycle.legal_access.test.csv +++ b/Profiles/bicycle/tests/bicycle.legal_access.test.csv @@ -12,7 +12,7 @@ designated,residential,designated,,,, designated,motorway,designated,,,, no,residential,use_sidepath,,,, yes,residential,,no,yes,, -no,primary,,,,, +yes,primary,,,,, yes,primary,,,,yes, yes,primary,,,,,yes yes,secondary,,,,track, diff --git a/Profiles/bicycle/tests/bicycle.safety.test.csv b/Profiles/bicycle/tests/bicycle.safety.test.csv index 3233bf5..b404ca2 100644 --- a/Profiles/bicycle/tests/bicycle.safety.test.csv +++ b/Profiles/bicycle/tests/bicycle.safety.test.csv @@ -1,8 +1,8 @@ expected,highway,cycleway,cyclestreet,foot,bicycle,cycleway:right,access -0.15,primary,no,,,,, -0.285,primary,yes,,,,, -0.45,primary,track,,,,, -0.4,secondary,lane,,,,, +0.1,primary,no,,,,, +0.115,primary,yes,,,,, +0.15,primary,track,,,,, +0.46,secondary,lane,,,,, 0.9,residential,,,,,, 1.5,cycleway,,,,,,designated 1.35,residential,,yes,,,, @@ -10,4 +10,4 @@ expected,highway,cycleway,cyclestreet,foot,bicycle,cycleway:right,access 0.9025,footway,,,designated,,, 1.2825,path,,,designated,designated,, 1.35,path,,,,designated,, -0.4,secondary,,,,,lane, +0.46,secondary,,,,,lane, diff --git a/Profiles/bicycle/tests/bicycle.shortest.behaviour_test.csv b/Profiles/bicycle/tests/bicycle.shortest.behaviour_test.csv index 5c45b83..c868087 100644 --- a/Profiles/bicycle/tests/bicycle.shortest.behaviour_test.csv +++ b/Profiles/bicycle/tests/bicycle.shortest.behaviour_test.csv @@ -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 -no,both,15,0,primary, +yes,both,15,1,primary,