Skip to content

Verification_Engine added #3431

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions BHoM_Engine.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.33927.289
# Visual Studio Version 17
VisualStudioVersion = 17.7.34302.85
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BHoM_Engine", "BHoM_Engine\BHoM_Engine.csproj", "{AEAF161D-8206-40B8-93A7-67ABEBF2EE19}"
EndProject
Expand Down Expand Up @@ -59,6 +59,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ground_Engine", "Ground_Eng
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Search_Engine", "Search_Engine\Search_Engine.csproj", "{7DDAC1D8-5B6A-471F-BC39-5B7E91A0E86C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Verification_Engine", "Verification_Engine\Verification_Engine.csproj", "{3AC2FA07-E889-484B-A319-B5CA942C277E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -177,6 +179,10 @@ Global
{7DDAC1D8-5B6A-471F-BC39-5B7E91A0E86C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7DDAC1D8-5B6A-471F-BC39-5B7E91A0E86C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7DDAC1D8-5B6A-471F-BC39-5B7E91A0E86C}.Release|Any CPU.Build.0 = Release|Any CPU
{3AC2FA07-E889-484B-A319-B5CA942C277E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3AC2FA07-E889-484B-A319-B5CA942C277E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3AC2FA07-E889-484B-A319-B5CA942C277E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3AC2FA07-E889-484B-A319-B5CA942C277E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
3 changes: 2 additions & 1 deletion BHoM_Engine/Query/ExtensionMethodHierarchy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ public static List<List<List<MethodInfo>>> ExtensionMethodHierarchy(this IEnumer
// Each item of the top list represents hierarchy for each input type
List<List<List<MethodInfo>>> result = new List<List<List<MethodInfo>>>();
int i = 0;
foreach(Type type in types)

foreach (Type type in types)
{
if (type == null)
{
Expand Down
170 changes: 170 additions & 0 deletions Verification_Engine/Compute/CompareValues.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
/*
* This file is part of the Buildings and Habitats object Model (BHoM)
* Copyright (c) 2015 - 2024, the respective contributors. All rights reserved.
*
* Each contributor holds copyright over their respective contributions.
* The project versioning (Git) records all such contribution source information.
*
*
* The BHoM is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3.0 of the License, or
* (at your option) any later version.
*
* The BHoM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this code. If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
*/

using BH.Engine.Base.Objects;
using BH.oM.Base;
using BH.oM.Base.Attributes;
using BH.oM.Verification;
using BH.oM.Verification.Conditions;
using System;
using System.ComponentModel;

namespace BH.Engine.Verification
{
public static partial class Compute
{
/***************************************************/
/**** Public Methods ****/
/***************************************************/

[Description("Compares two values using the provided comparison requirement and tolerance.")]
[Input("value", "Value to compare against the reference value.")]
[Input("referenceValue", "Reference value to compare the value against.")]
[Input("comparisonType", "Comparison requirement, i.e. whether the value should be equal, greater, less than reference value etc.")]
[Input("tolerance", "Tolerance to apply in the comparison.")]
[Output("result", "True if comparison of the input values meets the comparison requirement, otherwise false. Null in case of inconclusive comparison.")]
public static bool? CompareValues(this object value, object referenceValue, ValueComparisonType comparisonType, object tolerance)
{
// Basic cases (check for nullity)
if (referenceValue == null && value == null)
return true;
else if (referenceValue == null || value == null)
return false;

if (value is Type && referenceValue is Type)
return value == referenceValue;

// Try enum comparison
if (value is Enum || referenceValue is Enum)
return value.GetType() == referenceValue.GetType() && (int)value == (int)referenceValue;

// Try a numerical comparison
double numericalValue, referenceNumValue;
if (double.TryParse(value?.ToString(), out numericalValue) && double.TryParse(referenceValue?.ToString(), out referenceNumValue))
{
double numTolerance;
if (!double.TryParse(tolerance?.ToString(), out numTolerance))
numTolerance = 1e-03;

return NumericalComparison(numericalValue, referenceNumValue, numTolerance, comparisonType);
}

// Try string comparison
if (value is string && referenceValue is string)
return StringComparison((string)value, (string)referenceValue, comparisonType);

// Consider some other way to compare objects.
if (comparisonType == ValueComparisonType.EqualTo || comparisonType == ValueComparisonType.NotEqualTo)
{
bool? passed;

// If the referenceValue is a Type, convert this ValueCondition to a IsOfType condition.
if (referenceValue is Type)
{
IsOfType typeCondition = new IsOfType() { Type = referenceValue as Type };
passed = value.IPasses(typeCondition);
}
else
passed = CompareObjectEquality(value, referenceValue, tolerance);

if (passed != null && comparisonType == ValueComparisonType.NotEqualTo)
passed = !passed;

return passed;
}

BH.Engine.Base.Compute.RecordWarning("Objects could not be compared because no meaningful comparison method has been found.");
return null;
}


/***************************************************/
/**** Private Methods ****/
/***************************************************/

private static bool CompareObjectEquality(object value, object refValue, object tolerance)
{
if (value == null || refValue == null)
return value == refValue;

if (value.GetType() != refValue.GetType())
return false;

var cc = tolerance as ComparisonConfig;
if (cc != null)
{
HashComparer<object> hc = new HashComparer<object>(cc);
return hc.Equals(value, refValue);
}

return value.Equals(refValue);
}

/***************************************************/

private static bool? NumericalComparison(double value, double referenceValue, double tolerance, ValueComparisonType condition)
{
switch (condition)
{
case ValueComparisonType.EqualTo:
return (Math.Abs(value - referenceValue) <= tolerance);
case ValueComparisonType.NotEqualTo:
return (Math.Abs(value - referenceValue) > tolerance);
case ValueComparisonType.GreaterThan:
return (value - referenceValue > tolerance);
case ValueComparisonType.GreaterThanOrEqualTo:
return (value - referenceValue >= -tolerance);
case ValueComparisonType.LessThan:
return (value - referenceValue < -tolerance);
case ValueComparisonType.LessThanOrEqualTo:
return (value - referenceValue <= tolerance);
default:
BH.Engine.Base.Compute.RecordWarning($"Comparison of type {condition} is not supported for numbers.");
return null;
}
}

/***************************************************/

private static bool? StringComparison(string value, string referenceValue, ValueComparisonType condition)
{
switch (condition)
{
case ValueComparisonType.EqualTo:
return value == referenceValue;
case ValueComparisonType.NotEqualTo:
return value != referenceValue;
case ValueComparisonType.Contains:
return value.Contains(referenceValue);
case ValueComparisonType.StartsWith:
return value.StartsWith(referenceValue);
case ValueComparisonType.EndsWith:
return value.EndsWith(referenceValue);
default:
BH.Engine.Base.Compute.RecordWarning($"Comparison of type {condition} is not supported for strings.");
return null;
}
}

/***************************************************/
}
}
82 changes: 82 additions & 0 deletions Verification_Engine/Compute/Extract.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* This file is part of the Buildings and Habitats object Model (BHoM)
* Copyright (c) 2015 - 2024, the respective contributors. All rights reserved.
*
* Each contributor holds copyright over their respective contributions.
* The project versioning (Git) records all such contribution source information.
*
*
* The BHoM is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3.0 of the License, or
* (at your option) any later version.
*
* The BHoM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this code. If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
*/

using BH.oM.Base.Attributes;
using BH.oM.Verification.Extraction;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;

namespace BH.Engine.Verification
{
public static partial class Compute
{
/***************************************************/
/**** Interface Methods ****/
/***************************************************/

[Description("Extracts the objects from the input set based on the extraction instruction." +
"\nExtraction means either simple filtering from the input set or generation of derived objects based on the input set.")]
[Input("objects", "Set of objects to extract from.")]
[Input("extraction", "Instruction how to extract the objects from the input set.")]
[Output("extracted", "Collection of objects extracted from the input set based on the extraction instruction.")]
public static List<object> IExtract(this IEnumerable<object> objects, IExtraction extraction)
{
if (objects == null)
{
BH.Engine.Base.Compute.RecordError($"Extraction failed because the provided objects to extract from are null.");
return null;
}

if (extraction == null)
{
BH.Engine.Base.Compute.RecordNote("No filter provided, all input objects have been verified against the requirements.");
return objects.ToList();
}

object filtered;
if (!BH.Engine.Base.Compute.TryRunExtensionMethod(objects, nameof(Extract), new object[] { extraction }, out filtered))
{
BH.Engine.Base.Compute.RecordError($"Extraction failed because extraction type {extraction.GetType().Name} is currently not supported.");
return null;
}

return filtered as List<object>;
}


/***************************************************/
/**** Public Methods ****/
/***************************************************/

[Description("Extracts the objects from the input set based on the condition based filter.")]
[Input("objects", "Set of objects to extract from.")]
[Input("extraction", "Condition based filter, i.e. set of conditions for each object to pass in order to be returned.")]
[Output("extracted", "Subset of the input objects that passed the conditions embedded in the input filter.")]
public static List<object> Extract(this IEnumerable<object> objects, ConditionBasedFilter extraction)
{
return objects.Where(x => x.IPasses(extraction.Condition) == true).ToList();
}

/***************************************************/
}
}
Loading