├── Zen-Icon.png ├── .stylecop ├── AnalysisDictionary.xml ├── stylecop.json └── StyleCop.props ├── ZenLib ├── DataTypes │ ├── Unit.cs │ └── UInt.cs ├── Solver │ ├── SolverDebugInfo.cs │ ├── SolverType.cs │ └── SolverConfig.cs ├── Configuration │ ├── ZenObjectAttribute.cs │ ├── ZenGenerationConfiguration.cs │ ├── ZenSizeAttribute.cs │ └── ZenSettings.cs ├── ModelChecking │ ├── Backend │ │ ├── ModelCheckerContext.cs │ │ ├── SymbolicEvaluationEnvironment.cs │ │ ├── IModelChecker.cs │ │ ├── ZenSolution.cs │ │ └── ModelCheckerFactory.cs │ ├── InterleavingAnalysis │ │ ├── InterleavingResult.cs │ │ ├── InterleavingClass.cs │ │ └── InterleavingSet.cs │ ├── Transformer │ │ ├── StateSetMetadata.cs │ │ └── StateSetTransformerManager.cs │ └── Representation │ │ ├── SymbolicValue.cs │ │ ├── SymbolicReal.cs │ │ ├── SymbolicSeq.cs │ │ ├── SymbolicString.cs │ │ ├── SymbolicMap.cs │ │ ├── SymbolicInteger.cs │ │ ├── SymbolicBitvec.cs │ │ ├── SymbolicChar.cs │ │ ├── SymbolicBool.cs │ │ ├── SymbolicFSeq.cs │ │ ├── SymbolicConstMap.cs │ │ ├── ISymbolicValueVisitor.cs │ │ └── SymbolicObject.cs ├── Common │ ├── ZenTimeoutException.cs │ ├── ZenException.cs │ ├── ZenUnreachableException.cs │ ├── LazyString.cs │ ├── Contract.cs │ └── FiniteCache.cs ├── TransitionSystem │ ├── SearchStats.cs │ ├── SearchOutcome.cs │ ├── LTL │ │ ├── Predicate.cs │ │ ├── Or.cs │ │ ├── And.cs │ │ ├── Eventually.cs │ │ ├── Always.cs │ │ ├── Not.cs │ │ └── LTL.cs │ └── SearchResult.cs ├── Compilation │ └── ExpressionConverterEnvironment.cs ├── Interpreter │ ├── Interpreter.cs │ └── ExpressionEvaluatorEnvironment.cs ├── Language │ └── Ast │ │ ├── ZenEnumerableExtensions.cs │ │ ├── ZenLambda.cs │ │ ├── ZenArbitraryExpr.cs │ │ ├── ZenParameterExpr.cs │ │ ├── ZenAstCache.cs │ │ ├── ZenConstantExpr.cs │ │ ├── ZenSeqUnitExpr.cs │ │ ├── ZenSeqLengthExpr.cs │ │ ├── ZenCastExpr.cs │ │ ├── ZenBitwiseNotExpr.cs │ │ ├── ZenSeqRegexExpr.cs │ │ ├── ZenSeqNthExpr.cs │ │ ├── ZenSeqAtExpr.cs │ │ └── ZenFSeqAddFrontExpr.cs ├── Regex │ ├── Ast │ │ ├── RegexEmptyExpr.cs │ │ ├── RegexEpsilonExpr.cs │ │ ├── RegexAnchorExpr.cs │ │ └── RegexRangeExpr.cs │ └── Visitor │ │ └── IRegexExprVisitor.cs ├── Formatting │ └── ExpressionReuseVisitor.cs ├── ZenLib.csproj └── SymbolicExecution │ └── PathConstraint.cs ├── CODE_OF_CONDUCT.md ├── ZenLib.Tests ├── Network │ ├── Network.cs │ ├── Device.cs │ ├── ForwardingTable.cs │ ├── Interface.cs │ ├── LocatedPacket.cs │ ├── Prefix.cs │ └── Ip.cs ├── CharTests.cs ├── TimeoutTests.cs ├── ParallelismTests.cs ├── AttributeTests.cs ├── ZenLib.Tests.csproj ├── MemoryTests.cs ├── ApiTests.cs ├── FlyweightTests.cs ├── EnumerableExtensionsTests.cs ├── FindAllTests.cs ├── DebuggingTests.cs ├── ReflectionTests.cs ├── NatTests.cs └── RouteMapTests.cs ├── ZenLib.Generators.Tests ├── ZenLib.Generators.Tests.csproj └── Program.cs ├── ZenLib.Bench ├── Program.cs ├── ZenLib.Bench.csproj └── AclBench.cs ├── LICENSE ├── .github └── workflows │ └── dotnet.yml ├── ZenLib.Generators └── ZenLib.Generators.csproj └── SECURITY.md /Zen-Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/Zen/HEAD/Zen-Icon.png -------------------------------------------------------------------------------- /.stylecop/AnalysisDictionary.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | kusto 6 | 7 | 8 | -------------------------------------------------------------------------------- /.stylecop/stylecop.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", 3 | "description": "Configuration file for StyleCop Analyzers", 4 | "settings": { 5 | "documentationRules": { 6 | "companyName": "Microsoft" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /ZenLib/DataTypes/Unit.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib 6 | { 7 | /// 8 | /// Absence of a value. 9 | /// 10 | public sealed class Unit 11 | { 12 | /// 13 | /// The unit instance. 14 | /// 15 | public static Unit Instance = new Unit(); 16 | } 17 | } -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | -------------------------------------------------------------------------------- /ZenLib/Solver/SolverDebugInfo.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.Solver 6 | { 7 | using System; 8 | 9 | /// 10 | /// Solver debug information for Zen. 11 | /// 12 | public class SolverDebugInfo 13 | { 14 | /// 15 | /// The solver query that was used for Z3. 16 | /// 17 | public String SolverQuery; 18 | } 19 | } -------------------------------------------------------------------------------- /ZenLib.Tests/Network/Network.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.Tests.Network 6 | { 7 | using System.Collections.Generic; 8 | using System.Diagnostics.CodeAnalysis; 9 | 10 | /// 11 | /// Network object as a collection of devices. 12 | /// 13 | [ExcludeFromCodeCoverage] 14 | class Network 15 | { 16 | public Dictionary Devices { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ZenLib/Configuration/ZenObjectAttribute.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib 6 | { 7 | using System; 8 | 9 | /// 10 | /// Attribute annotation for classes and structs to generate zen methods. 11 | /// 12 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] 13 | public class ZenObjectAttribute : Attribute 14 | { 15 | } 16 | } -------------------------------------------------------------------------------- /ZenLib/Solver/SolverType.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.Solver 6 | { 7 | /// 8 | /// Solver type. 9 | /// 10 | public enum SolverType 11 | { 12 | /// 13 | /// DecisionDiagram backend. 14 | /// 15 | DecisionDiagrams, 16 | 17 | /// 18 | /// Z3 backend. 19 | /// 20 | Z3, 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ZenLib.Generators.Tests/ZenLib.Generators.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | latest 7 | AnyCPU;x64 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /ZenLib.Tests/Network/Device.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.Tests.Network 6 | { 7 | using System.Diagnostics.CodeAnalysis; 8 | 9 | /// 10 | /// A device objet. 11 | /// 12 | [ExcludeFromCodeCoverage] 13 | class Device 14 | { 15 | public string Name { get; set; } 16 | 17 | public ForwardingTable Table { get; set; } 18 | 19 | public Interface[] Interfaces { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ZenLib/ModelChecking/Backend/ModelCheckerContext.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.ModelChecking 6 | { 7 | /// 8 | /// The type of model checking to be performed. 9 | /// 10 | public enum ModelCheckerContext 11 | { 12 | /// 13 | /// Simple constraint solving. 14 | /// 15 | Solving, 16 | 17 | /// 18 | /// Constrained optimization. 19 | /// 20 | Optimization, 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ZenLib/Common/ZenTimeoutException.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib 6 | { 7 | using System; 8 | 9 | /// 10 | /// New exception type for a timeout in a solver for Zen.. 11 | /// 12 | public class ZenSolverTimeoutException : Exception 13 | { 14 | /// 15 | /// Creates a new instance of the class. 16 | /// 17 | public ZenSolverTimeoutException() : base() 18 | { 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ZenLib/Configuration/ZenGenerationConfiguration.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib 6 | { 7 | /// 8 | /// A generation configuration. 9 | /// 10 | internal class ZenGenerationConfiguration 11 | { 12 | /// 13 | /// The depth at which to generate objects. 14 | /// 15 | public int Depth { get; set; } 16 | 17 | /// 18 | /// An optional name to use for variables. 19 | /// 20 | public string Name { get; set; } 21 | } 22 | } -------------------------------------------------------------------------------- /ZenLib/TransitionSystem/SearchStats.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.TransitionSystem 6 | { 7 | /// 8 | /// The search statistics. 9 | /// 10 | public class SearchStats 11 | { 12 | /// 13 | /// The time taken in milliseconds. 14 | /// 15 | public long Time { get; } 16 | 17 | /// 18 | /// Creates a new instance of the class. 19 | /// 20 | /// The time. 21 | public SearchStats(long time) 22 | { 23 | Time = time; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ZenLib/TransitionSystem/SearchOutcome.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.TransitionSystem 6 | { 7 | /// 8 | /// The search outcome. 9 | /// 10 | public enum SearchOutcome 11 | { 12 | /// 13 | /// A counter example to the safety check. 14 | /// 15 | CounterExample, 16 | 17 | /// 18 | /// A proof that the system is safe. 19 | /// 20 | SafetyProof, 21 | 22 | /// 23 | /// A timeout for the verifier. 24 | /// 25 | Timeout, 26 | 27 | /// 28 | /// A lack of a counter example. 29 | /// 30 | NoCounterExample, 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ZenLib/Solver/SolverConfig.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.Solver 6 | { 7 | using System; 8 | 9 | /// 10 | /// Solver configuration for Zen. 11 | /// 12 | public class SolverConfig 13 | { 14 | /// 15 | /// The solver type to use. 16 | /// 17 | public SolverType SolverType { get; set; } = SolverType.Z3; 18 | 19 | /// 20 | /// The solver timeout to use. 21 | /// 22 | public TimeSpan? SolverTimeout { get; set; } = null; 23 | 24 | /// 25 | /// An optional debugging callback with the . 26 | /// 27 | public Action Debug { get; set; } = null; 28 | } 29 | } -------------------------------------------------------------------------------- /ZenLib.Bench/Program.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLibBench 6 | { 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Numerics; 10 | using ZenLib; 11 | using ZenLib.Solver; 12 | 13 | /// 14 | /// Run a collection of benchmarks for Zen. 15 | /// 16 | public class Program 17 | { 18 | /// 19 | /// Main entry point. 20 | /// 21 | /// Command line args. 22 | static void Main(string[] args) 23 | { 24 | // ZenBench.BenchmarkSets(); 25 | // ZenBench.BenchmarkComparisons(); 26 | // ZenBench.BenchmarkTransformers(); 27 | // ZenBench.BenchmarkTransformerCache(); 28 | // ZenBench.BenchmarkAllocation(); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ZenLib/Common/ZenException.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib 6 | { 7 | using System; 8 | 9 | /// 10 | /// New exception type for code known to be unreachable at runtime. 11 | /// 12 | public class ZenException : Exception 13 | { 14 | /// 15 | /// Creates a new instance of the class. 16 | /// 17 | /// 18 | public ZenException(string e) : base(e) 19 | { 20 | } 21 | 22 | /// 23 | /// Creates a new instance of the class. 24 | /// 25 | /// The description. 26 | /// The inner exception. 27 | public ZenException(string s, Exception innerException) : base(s, innerException) 28 | { 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ZenLib/Configuration/ZenSizeAttribute.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib 6 | { 7 | using System; 8 | 9 | /// 10 | /// Attribute annotation for fields that provides sizing information to Zen when 11 | /// generating symbolic values of a given type. 12 | /// 13 | [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, Inherited = false, AllowMultiple = false)] 14 | public class ZenSizeAttribute : Attribute 15 | { 16 | /// 17 | /// Initializes a new instance of the class. 18 | /// 19 | /// The depth for this field. 20 | public ZenSizeAttribute(int depth = -1) 21 | { 22 | Depth = depth; 23 | } 24 | 25 | /// 26 | /// Gets the size depth for the field or property. 27 | /// 28 | public int Depth { get; } 29 | } 30 | } -------------------------------------------------------------------------------- /ZenLib/Compilation/ExpressionConverterEnvironment.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.Compilation 6 | { 7 | using System.Collections.Immutable; 8 | using System.Linq.Expressions; 9 | 10 | /// 11 | /// An environment for the interpreter. 12 | /// 13 | internal class ExpressionConverterEnvironment 14 | { 15 | /// 16 | /// Initializes a new instance of the class. 17 | /// 18 | /// The initial argument assignment. 19 | public ExpressionConverterEnvironment(ImmutableDictionary argumentAssignment) 20 | { 21 | this.ArgumentAssignment = argumentAssignment; 22 | } 23 | 24 | /// 25 | /// Gets the argument assignment. 26 | /// 27 | public ImmutableDictionary ArgumentAssignment { get; } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ZenLib/Common/ZenUnreachableException.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib 6 | { 7 | using System; 8 | using System.Diagnostics.CodeAnalysis; 9 | 10 | /// 11 | /// Exception for unreachable code. 12 | /// 13 | [ExcludeFromCodeCoverage] 14 | public class ZenUnreachableException : ZenException 15 | { 16 | /// 17 | /// Creates a new instance of the class. 18 | /// 19 | public ZenUnreachableException() : base("Unexpected unreachable code detected.") 20 | { 21 | } 22 | 23 | /// 24 | /// Creates a new instance of the class. 25 | /// 26 | /// The inner exception. 27 | public ZenUnreachableException(Exception innerException) : base("Unexpected unreachable code detected.", innerException) 28 | { 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ZenLib/Configuration/ZenSettings.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib 6 | { 7 | using System; 8 | 9 | /// 10 | /// Settings for Zen. 11 | /// 12 | public static class ZenSettings 13 | { 14 | /// 15 | /// Use a larger stack to avoid stack overflow errors for 16 | /// large problem instances. Default is false. 17 | /// 18 | public static bool UseLargeStack = false; 19 | 20 | /// 21 | /// Maximum stack size since Zen uses deep recursion. 22 | /// 23 | public static int LargeStackSize = 30_000_000; 24 | 25 | /// 26 | /// Whether or not the preserve the structure of If branches. 27 | /// 28 | public static bool PreserveBranches = false; 29 | 30 | /// 31 | /// Whether we are in a separate thread with a larger stack already. 32 | /// 33 | [ThreadStatic] internal static bool InSeparateThread = false; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ZenLib.Generators.Tests/Program.cs: -------------------------------------------------------------------------------- 1 | namespace ZenLib.Generators.Tests; 2 | 3 | using ZenLib; 4 | 5 | partial class Program 6 | { 7 | static void Main(string[] args) 8 | { 9 | var x = Zen.Symbolic(); 10 | x.GetId(); 11 | x.GetBar(); 12 | x.WithBar(Zen.Symbolic()); 13 | x.WithId(Zen.Symbolic()); 14 | 15 | var y = Zen.Symbolic>(); 16 | y.GetField(); 17 | y.WithField(0); 18 | 19 | var z = Zen.Symbolic(); 20 | z.GetBlah(); 21 | z.WithBlah(0); 22 | } 23 | } 24 | 25 | [ZenObject] 26 | public class Point 27 | { 28 | public int X { get; set; } 29 | 30 | public int Y { get; set; } 31 | 32 | public static Zen Add(Zen p1, Zen p2) 33 | { 34 | return p1.WithX(p1.GetX() + p2.GetX()).WithY(p1.GetY() + p2.GetY()); 35 | } 36 | } 37 | 38 | [ZenObject] 39 | public class Foo 40 | { 41 | public Real Id { get; set; } 42 | 43 | public int Bar { get; set; } 44 | } 45 | 46 | [ZenObject] 47 | public class Bar 48 | { 49 | public uint Blah; 50 | } 51 | 52 | [ZenObject] 53 | public struct Fat 54 | { 55 | public T Field { get; set; } 56 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /ZenLib/ModelChecking/InterleavingAnalysis/InterleavingResult.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.ModelChecking 6 | { 7 | using System.Collections.Immutable; 8 | 9 | /// 10 | /// Representation of a an interleaving result. 11 | /// 12 | internal abstract class InterleavingResult 13 | { 14 | /// 15 | /// Gets all the possible variables the result could have. 16 | /// 17 | /// The variables as a set. 18 | public abstract ImmutableHashSet GetAllVariables(); 19 | 20 | /// 21 | /// Unions the two interleaving results. 22 | /// 23 | /// A new interleaving result. 24 | public abstract InterleavingResult Union(InterleavingResult other); 25 | 26 | /// 27 | /// Combine variables. 28 | /// 29 | /// The other result. 30 | /// The interleaved objects. 31 | public abstract void Combine(InterleavingResult other, UnionFind objects); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ZenLib.Tests/CharTests.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.Tests 6 | { 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Diagnostics.CodeAnalysis; 10 | using System.Linq; 11 | using Microsoft.VisualStudio.TestTools.UnitTesting; 12 | using ZenLib; 13 | using static ZenLib.Tests.TestHelper; 14 | using static ZenLib.Zen; 15 | 16 | /// 17 | /// Tests for the Zen bag type. 18 | /// 19 | [TestClass] 20 | [ExcludeFromCodeCoverage] 21 | public class CharTests 22 | { 23 | /// 24 | /// Test that conversions from strings and sequences works. 25 | /// 26 | [TestMethod] 27 | public void TestStringConversions1() 28 | { 29 | var s1 = "abcd"; 30 | var s2 = Seq.AsString(Seq.FromString(s1)); 31 | Assert.AreEqual(s1, s2); 32 | } 33 | 34 | /// 35 | /// Test that conversions from strings and sequences works. 36 | /// 37 | [TestMethod] 38 | public void TestStringConversions2() 39 | { 40 | var s1 = char.ConvertFromUtf32(0xffff); 41 | var s2 = Seq.AsString(Seq.FromString(s1)); 42 | Assert.AreEqual(s1, s2); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ZenLib/TransitionSystem/LTL/Predicate.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.TransitionSystem 6 | { 7 | using System; 8 | 9 | /// 10 | /// A predicate that should hold on a state. 11 | /// 12 | public class Predicate : LTL 13 | { 14 | /// 15 | /// The predicate for the state. 16 | /// 17 | public Func, Zen> Function { get; internal set; } 18 | 19 | /// 20 | /// Convert the spec to negated normal form. 21 | /// 22 | /// A spec in nnf. 23 | internal override LTL Nnf() 24 | { 25 | return this; 26 | } 27 | 28 | /// 29 | /// Encode the loop-free condition. 30 | /// 31 | /// The symbolic states. 32 | /// The current index. 33 | /// Variables for whether at a loop start. 34 | /// Variables for whehter in a loop. 35 | internal override Zen Encode(Zen[] states, Zen[] loopStart, Zen[] inLoop, int i) 36 | { 37 | Contract.Assert(i + 1 < states.Length); 38 | return this.Function(states[i]); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ZenLib/Interpreter/Interpreter.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.Interpretation 6 | { 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Collections.Immutable; 10 | using ZenLib.SymbolicExecution; 11 | using static ZenLib.Zen; 12 | 13 | /// 14 | /// Helper functions to interpret a Zen function. 15 | /// 16 | internal static class Interpreter 17 | { 18 | /// 19 | /// Execute an expression with some arguments. 20 | /// 21 | /// The function as an expression. 22 | /// The arguments with values as C# values. 23 | /// Whether to track branches. 24 | /// The result and any path constraint. 25 | public static (T, PathConstraint) Run(Zen expression, Dictionary args, bool trackBranches = false) 26 | { 27 | var environment = new ExpressionEvaluatorEnvironment { ArgumentAssignment = ImmutableDictionary.Empty.AddRange(args) }; 28 | var interpreter = new ExpressionEvaluatorVisitor(trackBranches); 29 | var result = (T)interpreter.Visit(expression, environment); 30 | return (result, interpreter.PathConstraint); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ZenLib.Bench/ZenLib.Bench.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | AnyCPU;x64 7 | 8 | 9 | 10 | x64 11 | C:\Users\rybecket\Desktop\workspace\projects\Zen\ZenLibBench\ZenLibBench.xml 12 | TRACE 13 | 14 | 15 | 16 | x64 17 | C:\Users\rybecket\Desktop\workspace\projects\Zen\ZenLibBench\ZenLibBench.xml 18 | TRACE 19 | 20 | 21 | 22 | x64 23 | 24 | 25 | 26 | x64 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /ZenLib/ModelChecking/Transformer/StateSetMetadata.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.ModelChecking 6 | { 7 | using System.Collections.Generic; 8 | using DecisionDiagrams; 9 | 10 | /// 11 | /// Represents a canonical set of BDD variables and Zen variables for state 12 | /// set and transformation operations. To allow for different variable orderings, 13 | /// a type T may have its BDD variables interleaved or not with other variables. 14 | /// However, to ensure operations can be performed we convert to and from a canonical 15 | /// variable set per type before doing the operation. This class carries that information. 16 | /// 17 | internal class StateSetMetadata 18 | { 19 | /// 20 | /// Represents the Zen input or output AST, which carries the arbitrary variables. 21 | /// 22 | public object ZenParameter { get; set; } 23 | 24 | /// 25 | /// The BDD variable set associated with the Zen Parameter. Used for quantification. 26 | /// 27 | public VariableSet VariableSet { get; set; } 28 | 29 | /// 30 | /// The mappping from Zen Arbitrary expression to BDD variable doing the encoding. 31 | /// 32 | public Dictionary> ZenArbitraryMapping { get; set; } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /.stylecop/StyleCop.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | False 6 | 7 | 8 | all 9 | runtime; build; native; contentfiles; analyzers; buildtransitive 10 | 11 | 12 | 13 | 14 | False 15 | 16 | 17 | 18 | 19 | ..\.stylecop\stylecop.ruleset 20 | true 21 | 22 | 26 | $(OutputPath)\$(AssemblyName).xml 27 | bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml 28 | 29 | 30 | -------------------------------------------------------------------------------- /.github/workflows/dotnet.yml: -------------------------------------------------------------------------------- 1 | name: .NET 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v3 16 | - name: Setup .NET 17 | uses: actions/setup-dotnet@v2 18 | with: 19 | dotnet-version: 6.0.x 20 | - name: Restore dependencies 21 | run: dotnet restore 22 | - name: Build 23 | run: dotnet build -c Release --no-restore 24 | - name: Test 25 | run: dotnet test -c Release --no-build --verbosity normal --collect:"XPlat Code Coverage" -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=opencover 26 | - name: Copy Coverage To Predictable Location 27 | run: cp ZenLib.Tests/TestResults/**/coverage.opencover.xml ZenLib.Tests/TestResults/coverage.opencover.xml 28 | - name: Create Test Coverage Badge 29 | uses: simon-k/dotnet-code-coverage-badge@v1.0.0 30 | id: create_coverage_badge 31 | with: 32 | label: Coverage 33 | color: brightgreen 34 | path: ZenLib.Tests/TestResults/coverage.opencover.xml 35 | gist-filename: code-coverage.json 36 | gist-id: 6623db8f2d0c01f6b2bc880e6219f97f 37 | gist-auth-token: ${{ secrets.GIST_AUTH_TOKEN }} 38 | - name: Print code coverage 39 | run: echo "Code coverage percentage ${{steps.create_coverage_badge.outputs.percentage}}%" 40 | - name: Print badge data 41 | run: echo "Badge data ${{steps.test_step.outputs.badge}}" -------------------------------------------------------------------------------- /ZenLib/Language/Ast/ZenEnumerableExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace ZenLib 6 | { 7 | /// 8 | /// Extensions of System.Linq for producing Zen expressions. 9 | /// Lifting of Linq methods to Zen types. 10 | /// 11 | public static class ZenEnumerableExtensions 12 | { 13 | /// 14 | /// Compute the or of an enumerable of values according to the given predicate. 15 | /// 16 | /// The enumerable. 17 | /// A predicate from the enumerable's element type to Zen booleans. 18 | /// The type of the enumerable's elements. 19 | /// Zen value. 20 | public static Zen Exists(this IEnumerable enumerable, Func> predicate) => 21 | enumerable.Aggregate(Zen.False(), (b, e) => Zen.Or(b, predicate(e))); 22 | 23 | /// 24 | /// Compute the and of an enumerable of values according to the given predicate. 25 | /// 26 | /// The enumerable. 27 | /// A predicate from the enumerable's element type to Zen booleans. 28 | /// The type of the enumerable's elements. 29 | /// Zen value. 30 | public static Zen ForAll(this IEnumerable enumerable, Func> predicate) => 31 | enumerable.Aggregate(Zen.True(), (b, e) => Zen.And(b, predicate(e))); 32 | } 33 | } -------------------------------------------------------------------------------- /ZenLib/ModelChecking/Representation/SymbolicValue.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.ModelChecking 6 | { 7 | using ZenLib.Solver; 8 | 9 | /// 10 | /// Representation of a symbolic value. 11 | /// 12 | internal abstract class SymbolicValue 13 | { 14 | /// 15 | /// The solver. 16 | /// 17 | public ISolver Solver; 18 | 19 | /// 20 | /// Creates a new instance of the class. 21 | /// 22 | /// The solver. 23 | public SymbolicValue(ISolver solver) 24 | { 25 | this.Solver = solver; 26 | } 27 | 28 | /// 29 | /// Accept a visitor. 30 | /// 31 | /// The visitor object. 32 | /// The parameter. 33 | /// The return value. 34 | internal abstract TReturn Accept( 35 | ISymbolicValueVisitor visitor, 36 | TParam parameter); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ZenLib/Language/Ast/ZenLambda.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib 6 | { 7 | using System; 8 | using System.Diagnostics.CodeAnalysis; 9 | 10 | /// 11 | /// A Zen lambda function. 12 | /// 13 | public sealed class ZenLambda 14 | { 15 | /// 16 | /// The C# function. 17 | /// 18 | internal Func, Zen> Function { get; private set; } 19 | 20 | /// 21 | /// The argument expression. 22 | /// 23 | internal ZenParameterExpr Parameter { get; private set; } 24 | 25 | /// 26 | /// The body expression. 27 | /// 28 | internal Zen Body { get; private set; } 29 | 30 | /// 31 | /// Initializes the lambda. 32 | /// 33 | public void Initialize(Func, Zen> function) 34 | { 35 | this.Function = function; 36 | this.Parameter = new ZenParameterExpr(); 37 | this.Body = function(this.Parameter); 38 | } 39 | 40 | /// 41 | /// Convert the expression to a string. 42 | /// 43 | /// The string representation. 44 | [ExcludeFromCodeCoverage] 45 | public override string ToString() 46 | { 47 | return $"lambda({this.Parameter} => {this.Body})"; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ZenLib/TransitionSystem/LTL/Or.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.TransitionSystem 6 | { 7 | /// 8 | /// A spec that takes the 'or' of two others. 9 | /// 10 | public class Or : LTL 11 | { 12 | /// 13 | /// The first formula. 14 | /// 15 | public LTL Formula1 { get; internal set; } 16 | 17 | /// 18 | /// The second formula. 19 | /// 20 | public LTL Formula2 { get; internal set; } 21 | 22 | /// 23 | /// Convert the spec to negated normal form. 24 | /// 25 | /// A spec in nnf. 26 | internal override LTL Nnf() 27 | { 28 | return LTL.Or(this.Formula1.Nnf(), this.Formula2.Nnf()); 29 | } 30 | 31 | /// 32 | /// Encode the loop-free condition. 33 | /// 34 | /// The symbolic states. 35 | /// The current index. 36 | /// Variables for whether at a loop start. 37 | /// Variables for whehter in a loop. 38 | internal override Zen Encode(Zen[] states, Zen[] loopStart, Zen[] inLoop, int i) 39 | { 40 | return Zen.Or( 41 | this.Formula1.Encode(states, loopStart, inLoop, i), 42 | this.Formula2.Encode(states, loopStart, inLoop, i)); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ZenLib/TransitionSystem/LTL/And.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.TransitionSystem 6 | { 7 | /// 8 | /// A spec that takes the 'and' of two others. 9 | /// 10 | public class And : LTL 11 | { 12 | /// 13 | /// The first formula. 14 | /// 15 | public LTL Formula1 { get; internal set; } 16 | 17 | /// 18 | /// The second formula. 19 | /// 20 | public LTL Formula2 { get; internal set; } 21 | 22 | /// 23 | /// Convert the spec to negated normal form. 24 | /// 25 | /// A spec in nnf. 26 | internal override LTL Nnf() 27 | { 28 | return LTL.And(this.Formula1.Nnf(), this.Formula2.Nnf()); 29 | } 30 | 31 | /// 32 | /// Encode the loop-free condition. 33 | /// 34 | /// The symbolic states. 35 | /// The current index. 36 | /// Variables for whether at a loop start. 37 | /// Variables for whehter in a loop. 38 | internal override Zen Encode(Zen[] states, Zen[] loopStart, Zen[] inLoop, int i) 39 | { 40 | return Zen.And( 41 | this.Formula1.Encode(states, loopStart, inLoop, i), 42 | this.Formula2.Encode(states, loopStart, inLoop, i)); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ZenLib/TransitionSystem/SearchResult.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.TransitionSystem 6 | { 7 | /// 8 | /// The search result. 9 | /// 10 | public class SearchResult 11 | { 12 | /// 13 | /// The outcome of the search. 14 | /// 15 | public SearchOutcome SearchOutcome { get; } 16 | 17 | /// 18 | /// The counter example, or null if none. 19 | /// 20 | public T[] CounterExample { get; } 21 | 22 | /// 23 | /// The depth of the search. 24 | /// 25 | public int Depth { get; } 26 | 27 | /// 28 | /// The statistics for the search. 29 | /// 30 | public SearchStats Stats { get; } 31 | 32 | /// 33 | /// Creates a new instance of the class. 34 | /// 35 | /// The depth of the search. 36 | /// The search outcome. 37 | /// The counter example. 38 | /// The statistics. 39 | public SearchResult(int depth, SearchOutcome searchOutcome, T[] counterExample, SearchStats stats) 40 | { 41 | this.Depth = depth; 42 | this.SearchOutcome = searchOutcome; 43 | this.CounterExample = counterExample; 44 | this.Stats = stats; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ZenLib.Tests/Network/ForwardingTable.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.Tests.Network 6 | { 7 | using System.Diagnostics.CodeAnalysis; 8 | using ZenLib; 9 | using static ZenLib.Zen; 10 | 11 | /// 12 | /// A forwarding table object. 13 | /// 14 | [ExcludeFromCodeCoverage] 15 | class ForwardingTable 16 | { 17 | public ForwardingRule[] Rules { get; set; } 18 | 19 | public Zen Forward(Zen packet, int i) 20 | { 21 | if (i == this.Rules.Length) 22 | { 23 | return Constant(0); // 0 is the null interface 24 | } 25 | 26 | var rule = this.Rules[i]; 27 | 28 | return If( 29 | rule.Matches(packet.GetCurrentHeader()), 30 | rule.Interface.PortNumber, 31 | Forward(packet, i + 1)); 32 | } 33 | } 34 | 35 | /// 36 | /// A forwarding rule object. 37 | /// 38 | [ExcludeFromCodeCoverage] 39 | class ForwardingRule 40 | { 41 | public Ip DstIpLow { get; set; } 42 | 43 | public Ip DstIpHigh { get; set; } 44 | 45 | public Interface Interface { get; set; } 46 | 47 | public Zen Matches(Zen hdr) 48 | { 49 | Zen dstLowMatch = hdr.GetDstIp().GetValue() >= this.DstIpLow.Value; 50 | Zen dstHighMatch = hdr.GetDstIp().GetValue() <= this.DstIpHigh.Value; 51 | return And(dstLowMatch, dstHighMatch); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ZenLib.Tests/TimeoutTests.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.Tests 6 | { 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Diagnostics.CodeAnalysis; 10 | using System.Numerics; 11 | using Microsoft.VisualStudio.TestTools.UnitTesting; 12 | using ZenLib.Solver; 13 | 14 | /// 15 | /// Tests that timeouts work with the solvers. 16 | /// 17 | [TestClass] 18 | [ExcludeFromCodeCoverage] 19 | public class TimeoutTests 20 | { 21 | /// 22 | /// Test that a timeout works. 23 | /// 24 | [TestMethod] 25 | [ExpectedException(typeof(ZenSolverTimeoutException))] 26 | public void TestTimeout() 27 | { 28 | ZenSettings.UseLargeStack = true; 29 | 30 | var variables = new Zen[2000]; 31 | 32 | var constraints = new List>(); 33 | var sum = Zen.Constant(BigInteger.Zero); 34 | for (int i = 0; i < 2000; i++) 35 | { 36 | variables[i] = Zen.Symbolic(); 37 | constraints.Add(variables[i] >= BigInteger.Zero); 38 | sum += variables[i]; 39 | } 40 | constraints.Add(sum == new BigInteger(3490)); 41 | 42 | // try to solve a big problem in a millisecond. 43 | var solverConfig = new SolverConfig 44 | { 45 | SolverType = SolverType.Z3, 46 | SolverTimeout = TimeSpan.FromMilliseconds(1), 47 | }; 48 | 49 | Zen.And(constraints.ToArray()).Solve(solverConfig); 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /ZenLib.Tests/ParallelismTests.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.Tests 6 | { 7 | using System.Diagnostics.CodeAnalysis; 8 | using System.Linq; 9 | using System.Threading.Tasks; 10 | using Microsoft.VisualStudio.TestTools.UnitTesting; 11 | using ZenLib; 12 | 13 | /// 14 | /// Tests for checking for thread-safety bugs. 15 | /// 16 | [TestClass] 17 | [ExcludeFromCodeCoverage] 18 | public class ParallelismTests 19 | { 20 | /// 21 | /// How many times to try to trigger thread safety issues. 22 | /// 23 | private static readonly int numIterations = 100; 24 | 25 | /// 26 | /// Solve multiple problems in parallel repeatedly. 27 | /// 28 | [TestMethod] 29 | public void TestMultithreadingFind() 30 | { 31 | Parallel.For(0, numIterations, (i) => 32 | { 33 | var zf = new ZenConstraint(x => x == i); 34 | var result = zf.Find(); 35 | Assert.AreEqual(i, result.Value); 36 | }); 37 | } 38 | 39 | /// 40 | /// Solve multiple problems in parallel repeatedly. 41 | /// 42 | [TestMethod] 43 | public void TestMultithreadingFindAll() 44 | { 45 | Parallel.For(0, numIterations, (i) => 46 | { 47 | var zf = new ZenConstraint(x => Zen.Or(x == i, x == i + 1)); 48 | var result = zf.FindAll().ToList(); 49 | Assert.AreEqual(2, result.Count); 50 | }); 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /ZenLib/Regex/Ast/RegexEmptyExpr.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib 6 | { 7 | using System; 8 | using System.Diagnostics.CodeAnalysis; 9 | 10 | /// 11 | /// Class representing a Regex empty expression. 12 | /// 13 | internal sealed class RegexEmptyExpr : Regex 14 | { 15 | /// 16 | /// The empty Regex instance. 17 | /// 18 | public static Regex Instance = new RegexEmptyExpr(); 19 | 20 | /// 21 | /// Initializes a new instance of the class. 22 | /// 23 | private RegexEmptyExpr() 24 | { 25 | } 26 | 27 | /// 28 | /// Convert the expression to a string. 29 | /// 30 | /// The string representation. 31 | [ExcludeFromCodeCoverage] 32 | public override string ToString() 33 | { 34 | return $"Empty"; 35 | } 36 | 37 | /// 38 | /// Implementing the visitor interface. 39 | /// 40 | /// The visitor object. 41 | /// The visitor parameter. 42 | /// The visitor parameter type. 43 | /// The visitor return type. 44 | /// A return value. 45 | internal override TReturn Accept(IRegexExprVisitor visitor, TParam parameter) 46 | { 47 | return visitor.Visit(this, parameter); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ZenLib.Tests/AttributeTests.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.Tests 6 | { 7 | using System.Diagnostics.CodeAnalysis; 8 | using Microsoft.VisualStudio.TestTools.UnitTesting; 9 | using ZenLib; 10 | using static ZenLib.Zen; 11 | 12 | /// 13 | /// Tests for the Zen object type. 14 | /// 15 | [TestClass] 16 | [ExcludeFromCodeCoverage] 17 | public class AttributeTests 18 | { 19 | /// 20 | /// Test that attributes work correctly for depth. 21 | /// 22 | [TestMethod] 23 | public void TestGenerationDepth() 24 | { 25 | // work around unused field warning. 26 | ObjectAttribute o1; 27 | o1.Field1 = new FSeq(); 28 | o1.Field2 = new FSeq(); 29 | o1.Field3 = new FSeq(); 30 | 31 | var o = Symbolic(depth: 3); 32 | var s1 = o.GetField>("Field1").ToString(); 33 | var s2 = o.GetField>("Field2").ToString(); 34 | var s3 = o.GetField>("Field3").ToString(); 35 | Assert.AreEqual(11, s1.Split("Cons").Length); 36 | Assert.AreEqual(6, s2.Split("Cons").Length); 37 | Assert.AreEqual(4, s3.Split("Cons").Length); 38 | } 39 | 40 | private struct ObjectAttribute 41 | { 42 | [ZenSize(depth: 10)] 43 | public FSeq Field1; 44 | 45 | [ZenSize(depth: 5)] 46 | public FSeq Field2; 47 | 48 | [ZenSize(depth: -1)] 49 | public FSeq Field3; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /ZenLib/Regex/Ast/RegexEpsilonExpr.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib 6 | { 7 | using System; 8 | using System.Diagnostics.CodeAnalysis; 9 | 10 | /// 11 | /// Class representing a Regex epsilon expression. 12 | /// 13 | internal sealed class RegexEpsilonExpr : Regex 14 | { 15 | /// 16 | /// The epsilon Regex instance. 17 | /// 18 | public static Regex Instance = new RegexEpsilonExpr(); 19 | 20 | /// 21 | /// Initializes a new instance of the class. 22 | /// 23 | private RegexEpsilonExpr() 24 | { 25 | } 26 | 27 | /// 28 | /// Convert the expression to a string. 29 | /// 30 | /// The string representation. 31 | [ExcludeFromCodeCoverage] 32 | public override string ToString() 33 | { 34 | return $"Epsilon"; 35 | } 36 | 37 | /// 38 | /// Implementing the visitor interface. 39 | /// 40 | /// The visitor object. 41 | /// The visitor parameter. 42 | /// The visitor parameter type. 43 | /// The visitor return type. 44 | /// A return value. 45 | internal override TReturn Accept(IRegexExprVisitor visitor, TParam parameter) 46 | { 47 | return visitor.Visit(this, parameter); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ZenLib.Tests/Network/Interface.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.Tests.Network 6 | { 7 | using System.Diagnostics.CodeAnalysis; 8 | using ZenLib; 9 | using static ZenLib.Zen; 10 | 11 | /// 12 | /// A device interface object. 13 | /// 14 | [ExcludeFromCodeCoverage] 15 | class Interface 16 | { 17 | public string Name { get; set; } 18 | 19 | public Device Owner { get; set; } 20 | 21 | public Interface Neighbor { get; set; } 22 | 23 | public byte PortNumber { get; set; } 24 | 25 | public Acl InboundAcl { get; set; } 26 | 27 | public Acl OutboundACl { get; set; } 28 | 29 | public (Ip, Ip)? GreTunnel { get; set; } 30 | 31 | public Zen Encapsulate(Zen packet) 32 | { 33 | if (this.GreTunnel.HasValue) 34 | { 35 | var oheader = packet.GetOverlayHeader(); 36 | var newSrcIp = this.GreTunnel.Value.Item1; 37 | var newDstIp = this.GreTunnel.Value.Item2; 38 | var uheader = IpHeader.Create( 39 | Ip.Create(newDstIp.Value), 40 | Ip.Create(newSrcIp.Value), 41 | oheader.GetDstPort(), 42 | oheader.GetSrcPort(), 43 | oheader.GetProtocol()); 44 | 45 | packet = Packet.Create(oheader, Option.Create(uheader)); 46 | } 47 | 48 | return packet; 49 | } 50 | 51 | public Zen Decapsulate(Zen packet) 52 | { 53 | if (this.GreTunnel.HasValue) 54 | { 55 | return Packet.Create(packet.GetOverlayHeader(), Option.Null()); 56 | } 57 | 58 | return packet; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /ZenLib.Tests/ZenLib.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | latest 6 | false 7 | AnyCPU;x64 8 | 9 | 10 | 11 | x64 12 | 13 | 14 | 15 | x64 16 | 17 | 18 | 19 | x64 20 | 21 | 22 | 23 | x64 24 | 25 | 26 | 27 | 28 | all 29 | runtime; build; native; contentfiles; analyzers; buildtransitive 30 | 31 | 32 | all 33 | runtime; build; native; contentfiles; analyzers; buildtransitive 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /ZenLib/TransitionSystem/LTL/Eventually.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.TransitionSystem 6 | { 7 | /// 8 | /// A property that must eventually hold. 9 | /// 10 | public class Eventually : LTL 11 | { 12 | /// 13 | /// The spec that should hold on a future state. 14 | /// 15 | public LTL Formula { get; internal set; } 16 | 17 | /// 18 | /// Convert the spec to negated normal form. 19 | /// 20 | /// A spec in nnf. 21 | internal override LTL Nnf() 22 | { 23 | return LTL.Eventually(this.Formula.Nnf()); 24 | } 25 | 26 | /// 27 | /// Encode the loop-free condition. 28 | /// 29 | /// The symbolic states. 30 | /// The current index. 31 | /// Variables for whether at a loop start. 32 | /// Variables for whehter in a loop. 33 | internal override Zen Encode(Zen[] states, Zen[] loopStart, Zen[] inLoop, int i) 34 | { 35 | if (i + 1 == states.Length) 36 | { 37 | var result = Zen.False(); 38 | for (int j = 0; j < i; j++) 39 | { 40 | result = Zen.Or(result, Zen.And(inLoop[j], this.Formula.Encode(states, loopStart, inLoop, j))); 41 | } 42 | 43 | return result; 44 | } 45 | else 46 | { 47 | return Zen.Or( 48 | this.Formula.Encode(states, loopStart, inLoop, i), 49 | this.Encode(states, loopStart, inLoop, i + 1)); 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ZenLib/Formatting/ExpressionReuseVisitor.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.Generation 6 | { 7 | using System.Collections.Generic; 8 | 9 | /// 10 | /// Class to identify sub-expressions that are repeated more than once. 11 | /// 12 | internal class ExpressionReuseVisitor : ZenExprActionVisitor 13 | { 14 | /// 15 | /// The subexpressions that are reused in this expression. 16 | /// 17 | private ISet reusedSubexpressions; 18 | 19 | /// 20 | /// Creates a new instance of the class. 21 | /// 22 | public ExpressionReuseVisitor() : base(new Dictionary()) 23 | { 24 | this.reusedSubexpressions = new HashSet(); 25 | } 26 | 27 | /// 28 | /// The set of reused subexpressions in this expression. 29 | /// 30 | /// The zen expression. 31 | /// The expression as a formatted string. 32 | public ISet GetReusedSubExpressions(Zen expression) 33 | { 34 | this.VisitCached(expression); 35 | return this.reusedSubexpressions; 36 | } 37 | 38 | /// 39 | /// Visit an expression. 40 | /// 41 | /// The expression. 42 | /// 43 | public override void VisitCached(Zen expression) 44 | { 45 | if (this.Visited.Contains(expression.Id)) 46 | { 47 | this.reusedSubexpressions.Add(expression); 48 | } 49 | else 50 | { 51 | this.Visited.Add(expression.Id); 52 | expression.Accept(this); 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ZenLib/TransitionSystem/LTL/Always.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.TransitionSystem 6 | { 7 | /// 8 | /// A property that must always hold. 9 | /// 10 | public class Always : LTL 11 | { 12 | /// 13 | /// The spec that should hold on every state. 14 | /// 15 | public LTL Formula { get; internal set; } 16 | 17 | /// 18 | /// Convert the spec to negated normal form. 19 | /// 20 | /// A spec in nnf. 21 | internal override LTL Nnf() 22 | { 23 | return LTL.Always(this.Formula.Nnf()); 24 | } 25 | 26 | /// 27 | /// Encode the loop-free condition. 28 | /// 29 | /// The symbolic states. 30 | /// The current index. 31 | /// Variables for whether at a loop start. 32 | /// Variables for whehter in a loop. 33 | internal override Zen Encode(Zen[] states, Zen[] loopStart, Zen[] inLoop, int i) 34 | { 35 | if (i + 1 == states.Length) 36 | { 37 | var loopExists = inLoop[i - 1]; 38 | 39 | var holdsInLoop = Zen.True(); 40 | for (int j = 0; j < i; j++) 41 | { 42 | holdsInLoop = Zen.And(holdsInLoop, Zen.Implies(inLoop[j], this.Formula.Encode(states, loopStart, inLoop, j))); 43 | } 44 | 45 | return Zen.And(loopExists, holdsInLoop); 46 | } 47 | else 48 | { 49 | return Zen.And( 50 | this.Formula.Encode(states, loopStart, inLoop, i), 51 | this.Encode(states, loopStart, inLoop, i + 1)); 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /ZenLib/Interpreter/ExpressionEvaluatorEnvironment.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.Interpretation 6 | { 7 | using System.Collections.Immutable; 8 | 9 | /// 10 | /// An environment for the interpreter. 11 | /// 12 | internal class ExpressionEvaluatorEnvironment 13 | { 14 | /// 15 | /// Gets the argument assignment. 16 | /// 17 | public ImmutableDictionary ArgumentAssignment { get; set; } = ImmutableDictionary.Empty; 18 | 19 | /// 20 | /// Get the arbitrary assignment. 21 | /// 22 | public ImmutableDictionary ArbitraryAssignment { get; set; } 23 | 24 | /// 25 | /// Whether we are in a lambda. 26 | /// 27 | public bool InLambda = false; 28 | 29 | /// 30 | /// Creates a new environment with the binding added. 31 | /// 32 | /// A new environment. 33 | public ExpressionEvaluatorEnvironment AddBinding(long id, object value) 34 | { 35 | return new ExpressionEvaluatorEnvironment 36 | { 37 | ArgumentAssignment = this.ArgumentAssignment.SetItem(id, value), 38 | ArbitraryAssignment = this.ArbitraryAssignment, 39 | InLambda = this.InLambda, 40 | }; 41 | } 42 | 43 | /// 44 | /// Creates a new environment noting that it is under a lambda. 45 | /// 46 | /// A new environment. 47 | public ExpressionEvaluatorEnvironment SetInLambda() 48 | { 49 | return new ExpressionEvaluatorEnvironment 50 | { 51 | ArgumentAssignment = this.ArgumentAssignment, 52 | ArbitraryAssignment = this.ArbitraryAssignment, 53 | InLambda = true, 54 | }; 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /ZenLib/ModelChecking/Backend/SymbolicEvaluationEnvironment.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.ModelChecking 6 | { 7 | using System.Collections.Generic; 8 | using System.Collections.Immutable; 9 | 10 | /// 11 | /// An environment for the symbolic evaluator. 12 | /// 13 | internal class SymbolicEvaluationEnvironment 14 | { 15 | /// 16 | /// Initializes a new instance of the class. 17 | /// 18 | public SymbolicEvaluationEnvironment(Dictionary argumentsToExpr) 19 | { 20 | this.ArgumentsToExpr = argumentsToExpr; 21 | this.ArgumentsToValue = ImmutableDictionary>.Empty; 22 | } 23 | 24 | /// 25 | /// Initializes a new instance of the class. 26 | /// 27 | /// The arguments to expr assignment. 28 | /// The initial argument assignment. 29 | public SymbolicEvaluationEnvironment( 30 | Dictionary argumentsToExpr, 31 | ImmutableDictionary> argumentAssignment) 32 | { 33 | this.ArgumentsToValue = argumentAssignment; 34 | this.ArgumentsToExpr = argumentsToExpr; 35 | } 36 | 37 | /// 38 | /// Gets the argument to value assignment. 39 | /// 40 | public ImmutableDictionary> ArgumentsToValue { get; } 41 | 42 | /// 43 | /// Gets the argument to expression assignment. 44 | /// 45 | public Dictionary ArgumentsToExpr { get; } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ZenLib/ModelChecking/Representation/SymbolicReal.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.ModelChecking 6 | { 7 | using System.Diagnostics.CodeAnalysis; 8 | using ZenLib.Solver; 9 | 10 | /// 11 | /// Representation of a symbolic real value. 12 | /// 13 | internal class SymbolicReal : SymbolicValue 14 | { 15 | /// 16 | /// The symbolic real value. 17 | /// 18 | public TReal Value { get; } 19 | 20 | /// 21 | /// Creates a new instance of the class. 22 | /// 23 | /// The solver. 24 | /// The symbolic value. 25 | public SymbolicReal(ISolver solver, TReal value) : base(solver) 26 | { 27 | this.Value = value; 28 | } 29 | 30 | /// 31 | /// Accept a visitor. 32 | /// 33 | /// The visitor object. 34 | /// The parameter. 35 | /// The return value. 36 | internal override TReturn Accept( 37 | ISymbolicValueVisitor visitor, 38 | TParam parameter) 39 | { 40 | return visitor.Visit(this, parameter); 41 | } 42 | 43 | /// 44 | /// Convert the object to a string. 45 | /// 46 | /// 47 | [ExcludeFromCodeCoverage] 48 | public override string ToString() 49 | { 50 | return $"={this.Value}"; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ZenLib/ModelChecking/Representation/SymbolicSeq.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.ModelChecking 6 | { 7 | using System.Diagnostics.CodeAnalysis; 8 | using ZenLib.Solver; 9 | 10 | /// 11 | /// Representation of a symbolic sequence value. 12 | /// 13 | internal class SymbolicSeq : SymbolicValue 14 | { 15 | /// 16 | /// The symbolic sequence value. 17 | /// 18 | public TSeq Value { get; } 19 | 20 | /// 21 | /// Creates a new instance of the class. 22 | /// 23 | /// The solver. 24 | /// The symbolic value. 25 | public SymbolicSeq(ISolver solver, TSeq value) : base(solver) 26 | { 27 | this.Value = value; 28 | } 29 | 30 | /// 31 | /// Accept a visitor. 32 | /// 33 | /// The visitor object. 34 | /// The parameter. 35 | /// The return value. 36 | internal override TReturn Accept( 37 | ISymbolicValueVisitor visitor, 38 | TParam parameter) 39 | { 40 | return visitor.Visit(this, parameter); 41 | } 42 | 43 | /// 44 | /// Convert the object to a string. 45 | /// 46 | /// 47 | [ExcludeFromCodeCoverage] 48 | public override string ToString() 49 | { 50 | return $"={this.Value}"; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ZenLib/ModelChecking/Representation/SymbolicString.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.ModelChecking 6 | { 7 | using System.Diagnostics.CodeAnalysis; 8 | using ZenLib.Solver; 9 | 10 | /// 11 | /// Representation of a symbolic string value. 12 | /// 13 | internal class SymbolicString : SymbolicValue 14 | { 15 | /// 16 | /// The symbolic string value. 17 | /// 18 | public TSeq Value { get; } 19 | 20 | /// 21 | /// Creates a new instance of the class. 22 | /// 23 | /// The solver. 24 | /// The symbolic value. 25 | public SymbolicString(ISolver solver, TSeq value) : base(solver) 26 | { 27 | this.Value = value; 28 | } 29 | 30 | /// 31 | /// Accept a visitor. 32 | /// 33 | /// The visitor object. 34 | /// The parameter. 35 | /// The return value. 36 | internal override TReturn Accept( 37 | ISymbolicValueVisitor visitor, 38 | TParam parameter) 39 | { 40 | return visitor.Visit(this, parameter); 41 | } 42 | 43 | /// 44 | /// Convert the object to a string. 45 | /// 46 | /// 47 | [ExcludeFromCodeCoverage] 48 | public override string ToString() 49 | { 50 | return ""; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ZenLib/ModelChecking/Representation/SymbolicMap.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.ModelChecking 6 | { 7 | using System.Diagnostics.CodeAnalysis; 8 | using ZenLib.Solver; 9 | 10 | /// 11 | /// Representation of a symbolic dictionary value. 12 | /// 13 | internal class SymbolicMap : SymbolicValue 14 | { 15 | /// 16 | /// The symbolic map value. 17 | /// 18 | public TArray Value { get; } 19 | 20 | /// 21 | /// Creates a new instance of the class. 22 | /// 23 | /// The solver. 24 | /// The symbolic value. 25 | public SymbolicMap(ISolver solver, TArray value) : base(solver) 26 | { 27 | this.Value = value; 28 | } 29 | 30 | /// 31 | /// Accept a visitor. 32 | /// 33 | /// The visitor object. 34 | /// The parameter. 35 | /// The return value. 36 | internal override TReturn Accept( 37 | ISymbolicValueVisitor visitor, 38 | TParam parameter) 39 | { 40 | return visitor.Visit(this, parameter); 41 | } 42 | 43 | /// 44 | /// Convert the object to a string. 45 | /// 46 | /// 47 | [ExcludeFromCodeCoverage] 48 | public override string ToString() 49 | { 50 | return $"={this.Value}"; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ZenLib/ModelChecking/Representation/SymbolicInteger.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.ModelChecking 6 | { 7 | using System.Diagnostics.CodeAnalysis; 8 | using ZenLib.Solver; 9 | 10 | /// 11 | /// Representation of a symbolic integer value. 12 | /// 13 | internal class SymbolicInteger : SymbolicValue 14 | { 15 | /// 16 | /// The symbolic integer value. 17 | /// 18 | public TInt Value { get; } 19 | 20 | /// 21 | /// Creates a new instance of the class. 22 | /// 23 | /// The solver. 24 | /// The symbolic value. 25 | public SymbolicInteger(ISolver solver, TInt value) : base(solver) 26 | { 27 | this.Value = value; 28 | } 29 | 30 | /// 31 | /// Accept a visitor. 32 | /// 33 | /// The visitor object. 34 | /// The parameter. 35 | /// The return value. 36 | internal override TReturn Accept( 37 | ISymbolicValueVisitor visitor, 38 | TParam parameter) 39 | { 40 | return visitor.Visit(this, parameter); 41 | } 42 | 43 | /// 44 | /// Convert the object to a string. 45 | /// 46 | /// 47 | [ExcludeFromCodeCoverage] 48 | public override string ToString() 49 | { 50 | return $"={this.Value}"; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ZenLib/ModelChecking/Representation/SymbolicBitvec.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.ModelChecking 6 | { 7 | using System.Diagnostics.CodeAnalysis; 8 | using ZenLib.Solver; 9 | 10 | /// 11 | /// Representation of a symbolic integer value. 12 | /// 13 | internal class SymbolicBitvec : SymbolicValue 14 | { 15 | /// 16 | /// The symbolic bitvector value. 17 | /// 18 | public TBitvec Value { get; } 19 | 20 | /// 21 | /// Create a new instance of the class. 22 | /// 23 | /// The solver. 24 | /// The bitvector value. 25 | public SymbolicBitvec(ISolver solver, TBitvec value) : base(solver) 26 | { 27 | this.Value = value; 28 | } 29 | 30 | /// 31 | /// Accept a visitor. 32 | /// 33 | /// The visitor object. 34 | /// The parameter. 35 | /// The return value. 36 | internal override TReturn Accept( 37 | ISymbolicValueVisitor visitor, 38 | TParam parameter) 39 | { 40 | return visitor.Visit(this, parameter); 41 | } 42 | 43 | /// 44 | /// Convert the object to a string. 45 | /// 46 | /// 47 | [ExcludeFromCodeCoverage] 48 | public override string ToString() 49 | { 50 | return $"={this.Value}"; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ZenLib/ModelChecking/Representation/SymbolicChar.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.ModelChecking 6 | { 7 | using System; 8 | using System.Diagnostics.CodeAnalysis; 9 | using ZenLib.Solver; 10 | 11 | /// 12 | /// Representation of a symbolic char value. 13 | /// 14 | internal class SymbolicChar : SymbolicValue 15 | { 16 | /// 17 | /// The symbolic character. 18 | /// 19 | public TChar Value { get; } 20 | 21 | /// 22 | /// Creates a new instance of the class. 23 | /// 24 | /// The solver. 25 | /// The symbolic value. 26 | public SymbolicChar(ISolver solver, TChar value) : base(solver) 27 | { 28 | this.Value = value; 29 | } 30 | 31 | /// 32 | /// Accept a visitor. 33 | /// 34 | /// The visitor object. 35 | /// The parameter. 36 | /// The return value. 37 | internal override TReturn Accept( 38 | ISymbolicValueVisitor visitor, 39 | TParam parameter) 40 | { 41 | return visitor.Visit(this, parameter); 42 | } 43 | 44 | /// 45 | /// Convert the object to a string. 46 | /// 47 | /// 48 | [ExcludeFromCodeCoverage] 49 | public override string ToString() 50 | { 51 | return $"={this.Value}"; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ZenLib.Tests/Network/LocatedPacket.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.Tests.Network 6 | { 7 | using System.Diagnostics.CodeAnalysis; 8 | using ZenLib; 9 | using static ZenLib.Zen; 10 | 11 | /// 12 | /// A packet with a location. 13 | /// 14 | [ExcludeFromCodeCoverage] 15 | public class LocatedPacket 16 | { 17 | /// 18 | /// Gets the node location as a byte. 19 | /// 20 | public byte Node { get; set; } 21 | 22 | /// 23 | /// Gets the Packet. 24 | /// 25 | public IpHeader Header { get; set; } 26 | } 27 | 28 | /// 29 | /// Helper class for LocatedPacket. 30 | /// 31 | [ExcludeFromCodeCoverage] 32 | public static class LocatedPacketHelper 33 | { 34 | /// 35 | /// Create a LocatedPacket. 36 | /// 37 | /// The node. 38 | /// The header. 39 | /// A LocatedPacket. 40 | public static Zen Create(Zen node, Zen header) 41 | { 42 | return Create(("Node", node), ("Header", header)); 43 | } 44 | 45 | /// 46 | /// Get the node of a LocatedPacket. 47 | /// 48 | /// The LocatedPacket. 49 | /// The node. 50 | public static Zen GetNode(this Zen lp) 51 | { 52 | return lp.GetField("Node"); 53 | } 54 | 55 | /// 56 | /// Get the Packet of a LocatedPacket. 57 | /// 58 | /// The LocatedPacket. 59 | /// The packet. 60 | public static Zen GetHeader(this Zen lp) 61 | { 62 | return lp.GetField("Header"); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /ZenLib.Tests/Network/Prefix.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.Tests.Network 6 | { 7 | using System; 8 | using System.Diagnostics.CodeAnalysis; 9 | using System.Net; 10 | using ZenLib; 11 | 12 | /// 13 | /// Simple packet class for testing. 14 | /// 15 | [ExcludeFromCodeCoverage] 16 | public class Prefix 17 | { 18 | /// 19 | /// The destination IP address. 20 | /// 21 | public uint Address { get; set; } 22 | 23 | /// 24 | /// The length of the prefix. 25 | /// 26 | public byte Length { get; set; } 27 | 28 | /// 29 | /// Check if this prefix contains a packet. 30 | /// 31 | /// The ip. 32 | /// Whether contained. 33 | public Zen Match(Zen ip) 34 | { 35 | var mask = 0xFFFFFFFF << (32 - this.Length); 36 | return (ip.GetValue() & mask) == (this.Address & mask); 37 | } 38 | 39 | /// 40 | /// Create a random prefix. 41 | /// 42 | /// 43 | public static Prefix Random(int low, int high) 44 | { 45 | var rnd = new Random(); 46 | var addr = (uint)rnd.Next(); 47 | var l = low + (rnd.Next() % (high - low + 1)); 48 | var mask = 0xFFFFFFFF << (32 - l); 49 | return new Prefix { Length = (byte)l, Address = addr & mask }; 50 | } 51 | 52 | /// 53 | /// Convert the prefix to a string. 54 | /// 55 | /// The string representation. 56 | public override string ToString() 57 | { 58 | var x1 = (Address >> 24) & 0x000000FF; 59 | var x2 = (Address >> 16) & 0x000000FF; 60 | var x3 = (Address >> 8) & 0x000000FF; 61 | var x4 = (Address >> 0) & 0x000000FF; 62 | 63 | return $"{x1}.{x2}.{x3}.{x4}/{Length}"; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /ZenLib/ModelChecking/Backend/IModelChecker.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.ModelChecking 6 | { 7 | using System.Collections.Generic; 8 | 9 | /// 10 | /// Interface for a model checker. 11 | /// 12 | internal interface IModelChecker 13 | { 14 | /// 15 | /// Find an input satisfying the expression via model checking. 16 | /// 17 | /// The boolean expression. 18 | /// The arguments. 19 | /// 20 | /// Mapping from zen arbitrary expression to value. 21 | /// Null if there is no input. 22 | /// 23 | Dictionary ModelCheck(Zen expression, Dictionary arguments); 24 | 25 | /// 26 | /// Find an input satisfying the expression via model checking. 27 | /// 28 | /// The expression to maximize. 29 | /// The constraints for the problem. 30 | /// The arguments. 31 | /// 32 | /// Mapping from zen arbitrary expression to value. 33 | /// Null if there is no input. 34 | /// 35 | Dictionary Maximize(Zen maximize, Zen subjectTo, Dictionary arguments); 36 | 37 | /// 38 | /// Find an input satisfying the expression via model checking. 39 | /// 40 | /// The expression to minimize. 41 | /// The constraints for the problem. 42 | /// The arguments. 43 | /// 44 | /// Mapping from zen arbitrary expression to value. 45 | /// Null if there is no input. 46 | /// 47 | Dictionary Minimize(Zen minimize, Zen subjectTo, Dictionary arguments); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /ZenLib/Language/Ast/ZenArbitraryExpr.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib 6 | { 7 | using System.Diagnostics.CodeAnalysis; 8 | 9 | /// 10 | /// A placeholder for an abtrary value of a given type. 11 | /// 12 | /// Type of an underlying C# value. 13 | internal sealed class ZenArbitraryExpr : Zen 14 | { 15 | /// 16 | /// The name, if any, for the expression. 17 | /// 18 | public string Name { get; } 19 | 20 | /// 21 | /// Initializes a new instance of the class. 22 | /// 23 | public ZenArbitraryExpr(string name) 24 | { 25 | Contract.AssertNotNull(name); 26 | this.Name = name; 27 | } 28 | 29 | /// 30 | /// Convert the expression to a string. 31 | /// 32 | /// The string representation. 33 | [ExcludeFromCodeCoverage] 34 | public override string ToString() 35 | { 36 | return this.Name; 37 | } 38 | 39 | /// 40 | /// Implementing the visitor interface. 41 | /// 42 | /// The visitor object. 43 | /// The visitor parameter. 44 | /// The visitor parameter type. 45 | /// The visitor return type. 46 | /// A return value. 47 | internal override TReturn Accept(ZenExprVisitor visitor, TParam parameter) 48 | { 49 | return visitor.VisitArbitrary(this, parameter); 50 | } 51 | 52 | /// 53 | /// Implementing the visitor interface. 54 | /// 55 | /// The visitor object. 56 | internal override void Accept(ZenExprActionVisitor visitor) 57 | { 58 | visitor.Visit(this); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /ZenLib/ModelChecking/Backend/ZenSolution.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.ModelChecking 6 | { 7 | using System.Collections.Generic; 8 | using ZenLib; 9 | using ZenLib.Interpretation; 10 | 11 | /// 12 | /// Represents a solution to a zen boolean expression. 13 | /// 14 | public class ZenSolution 15 | { 16 | /// 17 | /// Assignment from arbitrary variables to C# values. 18 | /// 19 | public Dictionary VariableAssignment; 20 | 21 | /// 22 | /// Creates a new instance of the class. 23 | /// 24 | /// The arbitrary assignment. 25 | internal ZenSolution(Dictionary arbitraryAssignment) 26 | { 27 | VariableAssignment = arbitraryAssignment; 28 | } 29 | 30 | /// 31 | /// Returns if the solution is satisfiable. 32 | /// 33 | /// True if the solution exists. 34 | public bool IsSatisfiable() 35 | { 36 | return VariableAssignment != null; 37 | } 38 | 39 | /// 40 | /// Gets a value from the assignment. 41 | /// 42 | /// The type of the expected value. 43 | /// The expression to get in the solution. 44 | /// The C# value associated with the expression. 45 | public T Get(Zen expr) 46 | { 47 | if (VariableAssignment != null && VariableAssignment.TryGetValue(expr, out var value)) 48 | { 49 | return (T)value; 50 | } 51 | 52 | var interpreterEnv = new ExpressionEvaluatorEnvironment { ArbitraryAssignment = System.Collections.Immutable.ImmutableDictionary.Empty.AddRange(VariableAssignment) }; 53 | var interpreter = new ExpressionEvaluatorVisitor(false); 54 | return (T)interpreter.Visit(expr, interpreterEnv); 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /ZenLib/ModelChecking/Transformer/StateSetTransformerManager.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.ModelChecking 6 | { 7 | using System; 8 | using System.Collections.Generic; 9 | using DecisionDiagrams; 10 | 11 | /// 12 | /// Manager object for transformers. Operations are only allowed between 13 | /// state sets and transformers with the same manager. 14 | /// 15 | public class StateSetTransformerManager 16 | { 17 | /// 18 | /// Manager object for building transformers. 19 | /// 20 | internal DDManager DecisionDiagramManager; 21 | 22 | /// 23 | /// Canonical variables used for a given type. 24 | /// 25 | internal Dictionary CanonicalValues; 26 | 27 | /// 28 | /// Keep track of, for each type, if there is an output 29 | /// of that type that is dependency free. 30 | /// 31 | internal Dictionary> DependencyFreeOutput; 32 | 33 | /// 34 | /// Cache for transformers. 35 | /// 36 | internal FiniteCache<(Type, long), object> TransformerCache; 37 | 38 | /// 39 | /// Cache for state sets. 40 | /// 41 | internal FiniteCache<(Type, long), object> StateSetCache; 42 | 43 | /// 44 | /// Creates a new instance of the class. 45 | /// 46 | /// The maximum cache size. 47 | public StateSetTransformerManager(int cacheSize = 1024) 48 | { 49 | this.DecisionDiagramManager = new DDManager(); 50 | this.CanonicalValues = new Dictionary(); 51 | this.DependencyFreeOutput = new Dictionary>(); 52 | this.TransformerCache = new FiniteCache<(Type, long), object>(cacheSize); 53 | this.StateSetCache = new FiniteCache<(Type, long), object>(cacheSize); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ZenLib.Tests/MemoryTests.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.Tests 6 | { 7 | using System; 8 | using System.Diagnostics.CodeAnalysis; 9 | using Microsoft.VisualStudio.TestTools.UnitTesting; 10 | 11 | /// 12 | /// Tests for memory reclaimation. 13 | /// 14 | [TestClass] 15 | [ExcludeFromCodeCoverage] 16 | public class MemoryTests 17 | { 18 | /* /// 19 | /// Test that we are able to reclaim memory after GC. 20 | /// 21 | [TestMethod] 22 | public void TestMemoryDecreasesAfterGc() 23 | { 24 | for (int i = 0; i < 1000000; i++) 25 | { 26 | var x = Zen.Constant(i); 27 | } 28 | 29 | var totalMemory1 = GC.GetTotalMemory(true) / 1000 / 1000; 30 | for (int i = 1000000; i < 2000000; i++) 31 | { 32 | var x = Zen.Constant(i); 33 | } 34 | 35 | var totalMemory2 = GC.GetTotalMemory(true) / 1000 / 1000; 36 | Assert.IsTrue(Math.Abs(totalMemory2 - totalMemory1) < 10); 37 | } 38 | 39 | /// 40 | /// Test that we are able to reuse expressions across functions. 41 | /// 42 | [TestMethod] 43 | public void TestMemoryReuseForSimilarFunctions() 44 | { 45 | var zf = new ZenFunction(x => CreateFunction(x, 0)); 46 | 47 | var totalMemory1 = GC.GetTotalMemory(true) / 1000 / 1000; 48 | var zfs = new ZenFunction[2000]; 49 | 50 | for (int i = 0; i < 2000; i++) 51 | { 52 | zfs[i] = new ZenFunction(x => CreateFunction(x, 0)); 53 | } 54 | 55 | var totalMemory2 = GC.GetTotalMemory(true) / 1000 / 1000; 56 | Assert.IsTrue(Math.Abs(totalMemory2 - totalMemory1) < 5); 57 | } 58 | 59 | private Zen CreateFunction(Zen x, int i) 60 | { 61 | if (i == 100) 62 | { 63 | return 100; 64 | } 65 | 66 | return Zen.If(x == i, 100 - i, CreateFunction(x, i + 1)); 67 | } */ 68 | } 69 | } -------------------------------------------------------------------------------- /ZenLib/Regex/Ast/RegexAnchorExpr.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib 6 | { 7 | using System.Diagnostics.CodeAnalysis; 8 | 9 | /// 10 | /// Class representing a Regex anchor. 11 | /// 12 | internal sealed class RegexAnchorExpr : Regex 13 | { 14 | /// 15 | /// The begin anchor Regex instance. 16 | /// 17 | public static Regex BeginInstance = new RegexAnchorExpr(true); 18 | 19 | /// 20 | /// The end anchor Regex instance. 21 | /// 22 | public static Regex EndInstance = new RegexAnchorExpr(false); 23 | 24 | /// 25 | /// Whether this is a begin anchor. 26 | /// 27 | [ExcludeFromCodeCoverage] 28 | public bool IsBegin { get; set; } 29 | 30 | /// 31 | /// Initializes a new instance of the class. 32 | /// 33 | /// Whether this is a begin anchor. 34 | private RegexAnchorExpr(bool isBegin) 35 | { 36 | this.IsBegin = isBegin; 37 | } 38 | 39 | /// 40 | /// Convert the expression to a string. 41 | /// 42 | /// The string representation. 43 | [ExcludeFromCodeCoverage] 44 | public override string ToString() 45 | { 46 | var anchorChar = this.IsBegin ? '^' : '$'; 47 | return $"Anchor({anchorChar})"; 48 | } 49 | 50 | /// 51 | /// Implementing the visitor interface. 52 | /// 53 | /// The visitor object. 54 | /// The visitor parameter. 55 | /// The visitor parameter type. 56 | /// The visitor return type. 57 | /// A return value. 58 | internal override TReturn Accept(IRegexExprVisitor visitor, TParam parameter) 59 | { 60 | return visitor.Visit(this, parameter); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /ZenLib/ZenLib.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.1 5 | © Microsoft Corporation. All rights reserved. 6 | Microsoft 7 | 8 | LICENSE 9 | https://github.com/microsoft/Zen 10 | https://github.com/microsoft/Zen 11 | A library that simplifies building verification tools in .NET 12 | zen zenlib modeling constraint solving verification smt solver binary decision diagrams diagram 13 | 3.1.6 14 | AnyCPU;x64 15 | Zen-Icon.png 16 | 17 | 18 | 19 | x64 20 | 21 | 22 | 23 | x64 24 | 25 | 26 | 27 | x64 28 | 29 | 30 | 31 | x64 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | <_Parameter1>$(MSBuildProjectName).Tests 47 | 48 | 49 | 50 | 51 | 52 | True 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /ZenLib/ModelChecking/Representation/SymbolicBool.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.ModelChecking 6 | { 7 | using System.Diagnostics.CodeAnalysis; 8 | using ZenLib.Solver; 9 | 10 | /// 11 | /// Representation of a symbolic boolean value. 12 | /// 13 | internal class SymbolicBool : SymbolicValue 14 | { 15 | /// 16 | /// The sybmolic boolean value. 17 | /// 18 | public TBool Value { get; } 19 | 20 | /// 21 | /// Creates a new instance of the class. 22 | /// 23 | /// The solver. 24 | /// The symbolic value. 25 | public SymbolicBool(ISolver solver, TBool value) : base(solver) 26 | { 27 | this.Value = value; 28 | } 29 | 30 | /// 31 | /// Accept a visitor. 32 | /// 33 | /// The visitor object. 34 | /// The parameter. 35 | /// The return value. 36 | internal override TReturn Accept( 37 | ISymbolicValueVisitor visitor, 38 | TParam parameter) 39 | { 40 | return visitor.Visit(this, parameter); 41 | } 42 | 43 | /// 44 | /// Convert the object to a string. 45 | /// 46 | /// 47 | [ExcludeFromCodeCoverage] 48 | public override string ToString() 49 | { 50 | if (this.Value.Equals(this.Solver.False())) 51 | { 52 | return "false"; 53 | } 54 | 55 | if (this.Value.Equals(this.Solver.True())) 56 | { 57 | return "true"; 58 | } 59 | 60 | return $"={this.Value}"; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /ZenLib.Tests/ApiTests.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.Tests 6 | { 7 | using System.Diagnostics.CodeAnalysis; 8 | using Microsoft.VisualStudio.TestTools.UnitTesting; 9 | using ZenLib; 10 | 11 | /// 12 | /// Tests for the Zen object type. 13 | /// 14 | [TestClass] 15 | [ExcludeFromCodeCoverage] 16 | public class ApiTests 17 | { 18 | /// 19 | /// Test that the solve method is working with evaluate. 20 | /// 21 | [TestMethod] 22 | public void TestSolve() 23 | { 24 | var x = Zen.Symbolic(); 25 | var solution = (x + 1 == 5).Solve(); 26 | 27 | Assert.IsTrue(solution.IsSatisfiable()); 28 | Assert.AreEqual(4, solution.VariableAssignment[x]); 29 | } 30 | 31 | /// 32 | /// Test that the evaluation function is working. 33 | /// 34 | [TestMethod] 35 | public void TestEvaluate() 36 | { 37 | Assert.AreEqual(int.MinValue, Zen.Evaluate((a) => a + 1, int.MaxValue)); 38 | 39 | Assert.AreEqual(1, Zen.Evaluate(() => Zen.Constant(1))); 40 | Assert.AreEqual(2, Zen.Evaluate((a) => a + 1, 1)); 41 | Assert.AreEqual(3, Zen.Evaluate((a, b) => a + b, 1, 2)); 42 | Assert.AreEqual(6, Zen.Evaluate((a, b, c) => a + b + c, 1, 2, 3)); 43 | Assert.AreEqual(10, Zen.Evaluate((a, b, c, d) => a + b + c + d, 1, 2, 3, 4)); 44 | } 45 | 46 | /// 47 | /// Test that the compilation function is working. 48 | /// 49 | [TestMethod] 50 | public void TestCompile() 51 | { 52 | var f1 = Zen.Compile(() => 1); 53 | var f2 = Zen.Compile((a) => a + 1); 54 | var f3 = Zen.Compile((a, b) => a + b); 55 | var f4 = Zen.Compile((a, b, c) => a + b + c); 56 | var f5 = Zen.Compile((a, b, c, d) => a + b + c + d); 57 | 58 | Assert.AreEqual(int.MinValue, f2(int.MaxValue)); 59 | 60 | Assert.AreEqual(1, f1()); 61 | Assert.AreEqual(2, f2(1)); 62 | Assert.AreEqual(3, f3(1, 2)); 63 | Assert.AreEqual(6, f4(1, 2, 3)); 64 | Assert.AreEqual(10, f5(1, 2, 3, 4)); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /ZenLib/ModelChecking/Representation/SymbolicFSeq.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.ModelChecking 6 | { 7 | using System.Collections.Immutable; 8 | using System.Diagnostics.CodeAnalysis; 9 | using System.Linq; 10 | using ZenLib.Solver; 11 | 12 | /// 13 | /// Representation of a symbolic boolean value. 14 | /// 15 | internal class SymbolicFSeq : SymbolicValue 16 | { 17 | /// 18 | /// The symbolic values in the list. 19 | /// 20 | public ImmutableList<(TBool, SymbolicValue)> Value { get; } 21 | 22 | /// 23 | /// Creates a new instance of the class. 24 | /// 25 | /// The solver. 26 | /// The symbolic value. 27 | public SymbolicFSeq( 28 | ISolver solver, 29 | ImmutableList<(TBool, SymbolicValue)> value) : base(solver) 30 | { 31 | this.Value = value; 32 | } 33 | 34 | /// 35 | /// Accept a visitor. 36 | /// 37 | /// The visitor object. 38 | /// The parameter. 39 | /// The return value. 40 | [ExcludeFromCodeCoverage] 41 | internal override TReturn Accept( 42 | ISymbolicValueVisitor visitor, 43 | TParam parameter) 44 | { 45 | return visitor.Visit(this, parameter); 46 | } 47 | 48 | /// 49 | /// Convert the object to a string. 50 | /// 51 | /// 52 | [ExcludeFromCodeCoverage] 53 | public override string ToString() 54 | { 55 | return $"=[{string.Join(",", this.Value.Select(x => x.ToString()))}]"; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /ZenLib.Tests/FlyweightTests.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.Tests 6 | { 7 | using System; 8 | using System.Diagnostics.CodeAnalysis; 9 | using Microsoft.VisualStudio.TestTools.UnitTesting; 10 | 11 | /// 12 | /// Tests the hash cons table. 13 | /// 14 | [TestClass] 15 | [ExcludeFromCodeCoverage] 16 | public class FlyweightTests 17 | { 18 | /// 19 | /// Test that Zen ids are working. 20 | /// 21 | [TestMethod] 22 | public void TestZenIds() 23 | { 24 | var x = Zen.Constant(1); 25 | var y = Zen.Constant(2); 26 | var z = x + x; 27 | 28 | Assert.AreEqual(y.Id, z.Id); 29 | Assert.AreNotEqual(x.Id, y.Id); 30 | Assert.AreNotEqual(x.Id, z.Id); 31 | } 32 | 33 | /// 34 | /// Test that insertion is working. 35 | /// 36 | [TestMethod] 37 | public void TestInsertion() 38 | { 39 | var ht = new Flyweight(); 40 | Check(ht); 41 | } 42 | 43 | /// 44 | /// Test that insertion works with garbage collection. 45 | /// 46 | [TestMethod] 47 | public void TestGarbageCollection() 48 | { 49 | var ht = new Flyweight(); 50 | Check(ht); 51 | GC.Collect(); 52 | Check(ht); 53 | } 54 | 55 | /// 56 | /// Checks insertion into the hash cons table. 57 | /// 58 | /// The table to use. 59 | private void Check(Flyweight ht) 60 | { 61 | Assert.IsTrue(ht.GetOrAdd(1, 1, (v) => v, out var _)); 62 | Assert.IsTrue(ht.GetOrAdd(2, 2, (v) => v, out var _)); 63 | Assert.IsFalse(ht.GetOrAdd(1, 1, (v) => v, out var _)); 64 | } 65 | 66 | /// 67 | /// Test that insertion works with garbage collection. 68 | /// 69 | [TestMethod] 70 | public void TestInsertMany() 71 | { 72 | var ht = new Flyweight(); 73 | 74 | for (int i = 0; i < 1000; i++) 75 | { 76 | Assert.IsTrue(ht.GetOrAdd(i, i, (v) => v, out var _)); 77 | } 78 | } 79 | } 80 | } -------------------------------------------------------------------------------- /ZenLib.Generators/ZenLib.Generators.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | © Microsoft Corporation. All rights reserved. 6 | Microsoft 7 | 8 | LICENSE 9 | https://github.com/microsoft/Zen 10 | https://github.com/microsoft/Zen 11 | Automatic generation of Zen field access methods. 12 | zen zenlib modeling constraint solving verification smt solver binary decision diagrams diagram 13 | 0.1.3 14 | 10 15 | false 16 | true 17 | AnyCPU;x64 18 | Zen-Icon.png 19 | 20 | 21 | 22 | x64 23 | 24 | 25 | 26 | x64 27 | 28 | 29 | 30 | x64 31 | 32 | 33 | 34 | x64 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | True 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /ZenLib/ModelChecking/Representation/SymbolicConstMap.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.ModelChecking 6 | { 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Collections.Immutable; 10 | using System.Diagnostics.CodeAnalysis; 11 | using ZenLib.Solver; 12 | 13 | /// 14 | /// Representation of a symbolic dictionary value. 15 | /// 16 | internal class SymbolicConstMap : SymbolicValue 17 | { 18 | /// 19 | /// The symbolic map from constants to symbolic values. 20 | /// 21 | public ImmutableDictionary> Value { get; } 22 | 23 | /// 24 | /// Creates a new instance of the class. 25 | /// 26 | /// The solver. 27 | /// The symbolic value. 28 | public SymbolicConstMap( 29 | ISolver solver, 30 | ImmutableDictionary> value) : base(solver) 31 | { 32 | this.Value = value; 33 | } 34 | 35 | /// 36 | /// Accept a visitor. 37 | /// 38 | /// The visitor object. 39 | /// The parameter. 40 | /// The return value. 41 | [ExcludeFromCodeCoverage] 42 | internal override TReturn Accept( 43 | ISymbolicValueVisitor visitor, 44 | TParam parameter) 45 | { 46 | return visitor.Visit(this, parameter); 47 | } 48 | 49 | /// 50 | /// Convert the object to a string. 51 | /// 52 | /// 53 | [ExcludeFromCodeCoverage] 54 | public override string ToString() 55 | { 56 | return ""; 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /ZenLib.Tests/EnumerableExtensionsTests.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics.CodeAnalysis; 2 | using System.Linq; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | 5 | namespace ZenLib.Tests; 6 | 7 | using static ZenLib.Tests.TestHelper; 8 | using static ZenLib.Zen; 9 | 10 | /// 11 | /// Tests for enumerable extension methods. 12 | /// 13 | [TestClass] 14 | [ExcludeFromCodeCoverage] 15 | public class EnumerableExtensionsTests 16 | { 17 | /// 18 | /// Test that exists of an empty enumerable is false. 19 | /// 20 | [TestMethod] 21 | public void TestExistsEmpty() 22 | { 23 | CheckAgreement(() => False() == Enumerable.Empty().Exists(_ => True())); 24 | } 25 | 26 | /// 27 | /// Test that exists of a 1-element enumerable is the element itself. 28 | /// 29 | [TestMethod] 30 | public void TestExistsSingle() 31 | { 32 | CheckValid(b => b == Enumerable.Repeat(b, 1).Exists(i => i)); 33 | } 34 | 35 | /// 36 | /// Test that exists of a 2-element enumerable is an or. 37 | /// 38 | [TestMethod] 39 | public void TestExistsTwo() 40 | { 41 | CheckValid((x, y) => Or(x, y) == new[] { x, y }.Exists(i => i)); 42 | } 43 | 44 | /// 45 | /// Test that exists of a 3-element enumerable is an or. 46 | /// 47 | [TestMethod] 48 | public void TestExistsThree() 49 | { 50 | CheckValid((x, y, z) => Or(x, y, z) == new[] { x, y, z }.Exists(i => i)); 51 | } 52 | 53 | /// 54 | /// Test that forall of an empty enumerable is true. 55 | /// 56 | [TestMethod] 57 | public void TestForAllEmpty() 58 | { 59 | CheckAgreement(() => True() == Enumerable.Empty().ForAll(_ => False())); 60 | } 61 | 62 | /// 63 | /// Test that forall of a 1-element enumerable is the element itself. 64 | /// 65 | [TestMethod] 66 | public void TestForAllSingle() 67 | { 68 | CheckValid(b => b == Enumerable.Repeat(b, 1).ForAll(i => i)); 69 | } 70 | 71 | /// 72 | /// Test that forall of a 2-element enumerable is an and. 73 | /// 74 | [TestMethod] 75 | public void TestForAllTwo() 76 | { 77 | CheckValid((x, y) => And(x, y) == new[] { x, y }.ForAll(i => i)); 78 | } 79 | 80 | /// 81 | /// Test that forall of a 3-element enumerable is an and. 82 | /// 83 | [TestMethod] 84 | public void TestForAllThree() 85 | { 86 | CheckValid((x, y, z) => And(x, y, z) == new[] { x, y, z }.ForAll(i => i)); 87 | } 88 | } -------------------------------------------------------------------------------- /ZenLib.Tests/FindAllTests.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.Tests 6 | { 7 | using System.Collections.Generic; 8 | using System.Diagnostics.CodeAnalysis; 9 | using System.Linq; 10 | using Microsoft.VisualStudio.TestTools.UnitTesting; 11 | using static ZenLib.Zen; 12 | 13 | /// 14 | /// Tests for finding multiple inputs. 15 | /// 16 | [TestClass] 17 | [ExcludeFromCodeCoverage] 18 | public class FindAllTests 19 | { 20 | /// 21 | /// Test that find all works. 22 | /// 23 | [TestMethod] 24 | public void TestFindAll() 25 | { 26 | Assert.AreEqual(11, new ZenFunction(x => x <= 10).FindAll((i, o) => o).Count()); 27 | Assert.AreEqual(2, new ZenFunction(x => And(x > 1, x <= 3)).FindAll((i, o) => o).Count()); 28 | Assert.AreEqual(5, new ZenFunction(x => x <= 4).FindAll((i, o) => o).Count()); 29 | 30 | Assert.AreEqual(2, new ZenFunction, bool>( 31 | x => And(x.Contains(1), x.Contains(2))).FindAll(depth: 2, invariant: (i, o) => o).Count()); 32 | 33 | Assert.AreEqual(6, new ZenFunction( 34 | (x, y) => And(x >= y, x <= 2)).FindAll((i1, i2, o) => o).Count()); 35 | 36 | Assert.AreEqual(24, new ZenFunction( 37 | (x, y, z) => And(x >= y, x <= 2, z <= 3)).FindAll((i1, i2, i3, o) => o).Count()); 38 | 39 | Assert.AreEqual(24, new ZenFunction( 40 | (x, y, z1, z2) => And(x >= y, x <= 2, z1 <= 1, z2 <= 1)).FindAll((i1, i2, i3, i4, o) => o).Count()); 41 | } 42 | 43 | /// 44 | /// Test that find all orders values in a deterministic way. 45 | /// 46 | [TestMethod] 47 | public void TestFindAllCorrect() 48 | { 49 | var values1 = new ZenFunction(x => x <= 10).FindAll((i, o) => o).ToList(); 50 | var values2 = new ZenFunction(x => x <= 10).FindAll((i, o) => o).ToList(); 51 | 52 | Assert.IsTrue(values1.TrueForAll(x => x <= 10)); 53 | Assert.IsTrue(values2.TrueForAll(x => x <= 10)); 54 | 55 | var unique1 = new HashSet(values1); 56 | var unique2 = new HashSet(values2); 57 | 58 | Assert.AreEqual(11, unique1.Count); 59 | Assert.AreEqual(11, unique2.Count); 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /ZenLib/Language/Ast/ZenParameterExpr.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib 6 | { 7 | using System.Diagnostics.CodeAnalysis; 8 | using System.Threading; 9 | 10 | /// 11 | /// A function argument placeholder expression.. 12 | /// 13 | /// Type of an underlying C# value. 14 | internal sealed class ZenParameterExpr : Zen 15 | { 16 | /// 17 | /// Gets the unique id for the object. 18 | /// 19 | public long ParameterId { get; } 20 | 21 | /// 22 | /// Initializes a new instance of the class. 23 | /// 24 | public ZenParameterExpr() 25 | { 26 | this.ParameterId = Interlocked.Increment(ref ZenArgumentId.nextId); 27 | } 28 | 29 | /// 30 | /// Convert the expression to a string. 31 | /// 32 | /// The string representation. 33 | [ExcludeFromCodeCoverage] 34 | public override string ToString() 35 | { 36 | return $"Param({this.ParameterId})"; 37 | } 38 | 39 | /// 40 | /// Implementing the visitor interface. 41 | /// 42 | /// The visitor object. 43 | /// The visitor parameter. 44 | /// The visitor parameter type. 45 | /// The visitor return type. 46 | /// A return value. 47 | internal override TReturn Accept(ZenExprVisitor visitor, TParam parameter) 48 | { 49 | return visitor.VisitParameter(this, parameter); 50 | } 51 | 52 | /// 53 | /// Implementing the visitor interface. 54 | /// 55 | /// The visitor object. 56 | internal override void Accept(ZenExprActionVisitor visitor) 57 | { 58 | visitor.Visit(this); 59 | } 60 | } 61 | 62 | /// 63 | /// Placeholder for the next unique id for an argument expression. 64 | /// This is kept outside the class to avoid having a separate id 65 | /// for each instantiation of the generic type T. 66 | /// 67 | internal static class ZenArgumentId 68 | { 69 | internal static long nextId; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /ZenLib/Regex/Visitor/IRegexExprVisitor.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib 6 | { 7 | /// 8 | /// Visitor interface for Regex. 9 | /// 10 | /// The regex character type. 11 | /// The parameter type. 12 | /// The return type. 13 | internal interface IRegexExprVisitor 14 | { 15 | /// 16 | /// Visit a RegexEmptyExpr. 17 | /// 18 | /// The expression. 19 | /// The parameter. 20 | /// A return value. 21 | TReturn Visit(RegexEmptyExpr expression, TParam parameter); 22 | 23 | /// 24 | /// Visit a RegexEpsilonExpr. 25 | /// 26 | /// The expression. 27 | /// The parameter. 28 | /// A return value. 29 | TReturn Visit(RegexEpsilonExpr expression, TParam parameter); 30 | 31 | /// 32 | /// Visit a RegexAnchorExpr. 33 | /// 34 | /// The expression. 35 | /// The parameter. 36 | /// A return value. 37 | TReturn Visit(RegexAnchorExpr expression, TParam parameter); 38 | 39 | /// 40 | /// Visit a RegexCharExpr. 41 | /// 42 | /// The expression. 43 | /// The parameter. 44 | /// A return value. 45 | TReturn Visit(RegexRangeExpr expression, TParam parameter); 46 | 47 | /// 48 | /// Visit a RegexUnopExpr. 49 | /// 50 | /// The expression. 51 | /// The parameter. 52 | /// A return value. 53 | TReturn Visit(RegexUnopExpr expression, TParam parameter); 54 | 55 | /// 56 | /// Visit a RegexBinopExpr. 57 | /// 58 | /// The expression. 59 | /// The parameter. 60 | /// A return value. 61 | TReturn Visit(RegexBinopExpr expression, TParam parameter); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /ZenLib/TransitionSystem/LTL/Not.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.TransitionSystem 6 | { 7 | using System.Diagnostics.CodeAnalysis; 8 | 9 | /// 10 | /// A spec that negates another. 11 | /// 12 | public class Not : LTL 13 | { 14 | /// 15 | /// The formula that negates another. 16 | /// 17 | public LTL Formula { get; internal set; } 18 | 19 | /// 20 | /// Convert the spec to negated normal form. 21 | /// 22 | /// A spec in nnf. 23 | internal override LTL Nnf() 24 | { 25 | // not(not(s)) == s 26 | if (Formula is Not s1) 27 | { 28 | return this.Formula.Nnf(); 29 | } 30 | 31 | // not(eventually(x)) == always(not(x)) 32 | if (Formula is Eventually s2) 33 | { 34 | var inner = LTL.Not(s2.Formula); 35 | return LTL.Always(inner.Nnf()); 36 | } 37 | 38 | // not(always(x)) == eventually(not(x)) 39 | if (Formula is Always s3) 40 | { 41 | var inner = LTL.Not(s3.Formula); 42 | return LTL.Eventually(inner.Nnf()); 43 | } 44 | 45 | // not(and(x, y)) == or(not(x), not(y)) 46 | if (Formula is And s4) 47 | { 48 | return LTL.Or(LTL.Not(s4.Formula1), LTL.Not(s4.Formula2)).Nnf(); 49 | } 50 | 51 | // not(or(x, y)) == and(not(x), not(y)) 52 | if (Formula is Or s5) 53 | { 54 | return LTL.And(LTL.Not(s5.Formula1), LTL.Not(s5.Formula2)).Nnf(); 55 | } 56 | 57 | // not(f(s)) = f(not(s)) 58 | var s6 = (Predicate)Formula; 59 | return LTL.Predicate(s => Zen.Not(s6.Function(s))); 60 | } 61 | 62 | /// 63 | /// Encode the loop-free condition. 64 | /// 65 | /// The symbolic states. 66 | /// The current index. 67 | /// Variables for whether at a loop start. 68 | /// Variables for whehter in a loop. 69 | [ExcludeFromCodeCoverage] 70 | internal override Zen Encode(Zen[] states, Zen[] loopStart, Zen[] inLoop, int i) 71 | { 72 | throw new ZenUnreachableException(); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /ZenLib/Language/Ast/ZenAstCache.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib 6 | { 7 | using System.Collections.Generic; 8 | using System.Diagnostics.CodeAnalysis; 9 | 10 | /// 11 | /// A cache for Zen ast expressions. 12 | /// 13 | internal static class ZenAstCache where TValue : class 14 | { 15 | /// 16 | /// A flyweight object that stores the expressions for each key. 17 | /// The object type TObj is to ensure that different flyweights are used 18 | /// for each AST node type. This ensures better parallelism. 19 | /// 20 | internal static Flyweight Flyweight = new Flyweight(); 21 | 22 | /// 23 | /// Hash cons table for ZenCreateObjectExpr. 24 | /// 25 | internal static Flyweight FlyweightArray = new Flyweight(new ArrayComparer()); 26 | 27 | /// 28 | /// Custom array comparer for ensuring hash consing uniqueness. 29 | /// 30 | [ExcludeFromCodeCoverage] 31 | private class ArrayComparer : IEqualityComparer 32 | { 33 | /// 34 | /// Equality for key arrays. 35 | /// 36 | /// The first array. 37 | /// The second array. 38 | /// True or false. 39 | public bool Equals(object[] a1, object[] a2) 40 | { 41 | if (a1.Length != a2.Length) 42 | { 43 | return false; 44 | } 45 | 46 | for (int i = 0; i < a1.Length; i++) 47 | { 48 | if (!a1[i].Equals(a2[i])) 49 | { 50 | return false; 51 | } 52 | } 53 | 54 | return true; 55 | } 56 | 57 | /// 58 | /// Hash code for the keys. 59 | /// 60 | /// The array of keys. 61 | /// An integer. 62 | public int GetHashCode(object[] array) 63 | { 64 | int result = 31; 65 | for (int i = 0; i < array.Length; i++) 66 | { 67 | result = result * 7 + array[i].GetHashCode(); 68 | } 69 | 70 | return result; 71 | } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /ZenLib.Tests/Network/Ip.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.Tests.Network 6 | { 7 | using System.Diagnostics.CodeAnalysis; 8 | using System.Net; 9 | using ZenLib; 10 | 11 | /// 12 | /// A simple IP address. 13 | /// 14 | [ExcludeFromCodeCoverage] 15 | public struct Ip 16 | { 17 | /// 18 | /// The value for the ip. 19 | /// 20 | public uint Value { get; set; } 21 | 22 | /// 23 | /// Create a Zen ip from a value. 24 | /// 25 | /// The value. 26 | /// The ip. 27 | public static Zen Create(Zen value) 28 | { 29 | return Zen.Create(("Value", value)); 30 | } 31 | 32 | /// 33 | /// Parse an ip from a string. 34 | /// 35 | /// The string. 36 | /// The ip. 37 | public static Ip Parse(string s) 38 | { 39 | var bytes = IPAddress.Parse(s).GetAddressBytes(); 40 | return FromBytes(bytes[0], bytes[1], bytes[2], bytes[3]); 41 | } 42 | 43 | /// 44 | /// Convert the ip to a string format. 45 | /// 46 | /// The string. 47 | public override string ToString() 48 | { 49 | var x1 = (this.Value >> 0) & 0x000000FF; 50 | var x2 = (this.Value >> 8) & 0x000000FF; 51 | var x3 = (this.Value >> 16) & 0x000000FF; 52 | var x4 = (this.Value >> 24) & 0x000000FF; 53 | return $"{x4}.{x3}.{x2}.{x1}"; 54 | } 55 | 56 | /// 57 | /// Create an ip from bytes. 58 | /// 59 | /// The first octet. 60 | /// The second octet. 61 | /// The third octet. 62 | /// The fourth octet. 63 | /// An ip address. 64 | public static Ip FromBytes(byte x1, byte x2, byte x3, byte x4) 65 | { 66 | return new Ip { Value = (uint)(x1 << 24) | (uint)(x2 << 16) | (uint)(x3 << 8) | x4 }; 67 | } 68 | } 69 | 70 | /// 71 | /// Ip extension methods. 72 | /// 73 | [ExcludeFromCodeCoverage] 74 | static class IpExtensions 75 | { 76 | public static Zen GetValue(this Zen ip) 77 | { 78 | return ip.GetField("Value"); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /ZenLib/SymbolicExecution/PathConstraint.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.SymbolicExecution 6 | { 7 | using System.Collections.Immutable; 8 | using System.Linq; 9 | 10 | /// 11 | /// A path constraint. 12 | /// 13 | internal class PathConstraint 14 | { 15 | /// 16 | /// Gets the current path constraint. 17 | /// 18 | public ImmutableList> Conjuncts { get; } 19 | 20 | /// 21 | /// Initializes a new instance of the class. 22 | /// 23 | public PathConstraint() 24 | { 25 | this.Conjuncts = ImmutableList>.Empty; 26 | } 27 | 28 | /// 29 | /// Add a guard to the path constraint. 30 | /// 31 | /// The guard. 32 | /// A new path constraint. 33 | public PathConstraint Add(Zen guard) 34 | { 35 | return new PathConstraint(this.Conjuncts.Add(guard)); 36 | } 37 | 38 | /// 39 | /// Get a new path constraint from a range of conjuncts. 40 | /// 41 | /// The lower index. 42 | /// The upper index. 43 | /// A new path constraint. 44 | public PathConstraint GetRange(int i, int j) 45 | { 46 | if (j < 0) 47 | { 48 | return new PathConstraint(); 49 | } 50 | 51 | var conjuncts = this.Conjuncts.GetRange(i, j - i + 1); 52 | return new PathConstraint(conjuncts); 53 | } 54 | 55 | /// 56 | /// Gets a Zen expression from a path constraint. 57 | /// 58 | /// The Zen expression. 59 | public Zen GetExpr() 60 | { 61 | var conjuncts = this.Conjuncts.ToArray(); 62 | 63 | if (conjuncts.Length == 0) 64 | { 65 | return Zen.True(); 66 | } 67 | 68 | return Zen.And(conjuncts); 69 | } 70 | 71 | /// 72 | /// Initializes a new instance of the class. 73 | /// 74 | /// The conjuncts. 75 | private PathConstraint(ImmutableList> pathConstraint) 76 | { 77 | this.Conjuncts = pathConstraint; 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /ZenLib.Bench/AclBench.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLibBench 6 | { 7 | using System; 8 | using System.Collections.Generic; 9 | using System.IO; 10 | using BenchmarkDotNet.Attributes; 11 | using ZenLib; 12 | using ZenLib.Solver; 13 | using ZenLib.Tests.Network; 14 | 15 | using static ZenLib.Zen; 16 | 17 | /// 18 | /// Benchmark for encoding ACLs of various sizes. 19 | /// 20 | [CsvExporter] 21 | [SimpleJob(targetCount: 30)] 22 | public class AclBench 23 | { 24 | /// 25 | /// The backend to use. 26 | /// 27 | [Params(SolverType.DecisionDiagrams, SolverType.Z3)] 28 | public SolverType Backend { get; set; } 29 | 30 | /// 31 | /// The number of ACL lines to benchmark. 32 | /// 33 | [Params(0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000, 12000, 13000, 14000, 15000)] 34 | public int NumLines { get; set; } 35 | 36 | /// 37 | /// The ACL. 38 | /// 39 | public Acl Acl; 40 | 41 | /// 42 | /// Create a deterministic random ACL of a given size. 43 | /// 44 | [GlobalSetup] 45 | public void CreateAcl() 46 | { 47 | var rnd = new Random(42); 48 | var lines = new List(); 49 | for (int i = 0; i < this.NumLines; i++) 50 | { 51 | var line = new AclLine 52 | { 53 | Permitted = (rnd.Next() & 1) == 0, 54 | DstIp = Prefix.Random(24, 32), 55 | SrcIp = Prefix.Random(24, 32), 56 | }; 57 | 58 | lines.Add(line); 59 | } 60 | 61 | // add default deny 62 | var defaultPrefix = new Prefix { Length = 0, Address = 0U }; 63 | lines.Add(new AclLine { DstIp = defaultPrefix, SrcIp = defaultPrefix }); 64 | 65 | this.Acl = new Acl { Lines = lines.ToArray() }; 66 | } 67 | 68 | /// 69 | /// Find a packet that does not match any line of the ACL. 70 | /// 71 | [Benchmark] 72 | public void VerifyAclProvenance() 73 | { 74 | var f = new ZenFunction>(h => this.Acl.ProcessProvenance(h)); 75 | var config = new SolverConfig { SolverType = this.Backend }; 76 | var packet = f.Find((p, o) => o.Item2() == (ushort)(this.Acl.Lines.Length + 1), config: config); 77 | f.Evaluate(packet.Value); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd). 40 | 41 | -------------------------------------------------------------------------------- /ZenLib/Common/LazyString.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib 6 | { 7 | using System.Text; 8 | 9 | /// 10 | /// A string that delays expensive concatenation. 11 | /// It represents concatenations by building tree of concatenated strings. 12 | /// 13 | internal class LazyString 14 | { 15 | /// 16 | /// The string value for this node. 17 | /// 18 | private string value; 19 | 20 | /// 21 | /// The left string node. 22 | /// 23 | private LazyString left; 24 | 25 | /// 26 | /// The right string node. 27 | /// 28 | private LazyString right; 29 | 30 | /// 31 | /// The length of the string. 32 | /// 33 | public int Length { get; } 34 | 35 | /// 36 | /// Creates a new instance of the class. 37 | /// 38 | /// The string value. 39 | public LazyString(string value) 40 | { 41 | this.value = value; 42 | this.left = null; 43 | this.right = null; 44 | this.Length = this.value.Length; 45 | } 46 | 47 | /// 48 | /// Creates a new instance of the class. 49 | /// 50 | /// 51 | /// 52 | private LazyString(LazyString left, LazyString right) 53 | { 54 | this.value = null; 55 | this.left = left; 56 | this.right = right; 57 | this.Length = this.left.Length + this.right.Length; 58 | } 59 | 60 | /// 61 | /// Concatenate two strings together. 62 | /// 63 | /// The first string. 64 | /// The second string. 65 | /// 66 | public static LazyString operator +(LazyString s1, LazyString s2) 67 | { 68 | return new LazyString(s1, s2); 69 | } 70 | 71 | /// 72 | /// Write this value to a string builder. 73 | /// 74 | /// The string builder. 75 | public void Write(StringBuilder sb) 76 | { 77 | if (this.left != null) 78 | { 79 | this.left.Write(sb); 80 | } 81 | 82 | if (this.value != null) 83 | { 84 | sb.Append(this.value); 85 | } 86 | 87 | if (this.right != null) 88 | { 89 | this.right.Write(sb); 90 | } 91 | } 92 | } 93 | } -------------------------------------------------------------------------------- /ZenLib/Language/Ast/ZenConstantExpr.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib 6 | { 7 | using System.Diagnostics.CodeAnalysis; 8 | 9 | /// 10 | /// Class representing a constant expression. 11 | /// 12 | internal sealed class ZenConstantExpr : Zen 13 | { 14 | /// 15 | /// Gets the value. 16 | /// 17 | internal T Value { get; } 18 | 19 | /// 20 | /// Simplify and create a new ZenBitwiseNot expr. 21 | /// 22 | /// The constant. 23 | /// The new expr. 24 | private static Zen Simplify(T c) => new ZenConstantExpr(c); 25 | 26 | /// 27 | /// Create a new ZenConstantExpr. 28 | /// 29 | /// The constant value. 30 | /// The Zen expr. 31 | public static Zen Create(T value) 32 | { 33 | var flyweight = ZenAstCache, Zen>.Flyweight; 34 | flyweight.GetOrAdd(value, value, Simplify, out var v); 35 | return v; 36 | } 37 | 38 | /// 39 | /// Initializes a new instance of the class. 40 | /// 41 | /// The value. 42 | private ZenConstantExpr(T value) 43 | { 44 | this.Value = value; 45 | } 46 | 47 | /// 48 | /// Convert the expression to a string. 49 | /// 50 | /// The string representation. 51 | [ExcludeFromCodeCoverage] 52 | public override string ToString() 53 | { 54 | return this.Value.ToString(); 55 | } 56 | 57 | /// 58 | /// Implementing the visitor interface. 59 | /// 60 | /// The visitor object. 61 | /// The visitor parameter. 62 | /// The visitor parameter type. 63 | /// The visitor return type. 64 | /// A return value. 65 | internal override TReturn Accept(ZenExprVisitor visitor, TParam parameter) 66 | { 67 | return visitor.VisitConstant(this, parameter); 68 | } 69 | 70 | /// 71 | /// Implementing the visitor interface. 72 | /// 73 | /// The visitor object. 74 | internal override void Accept(ZenExprActionVisitor visitor) 75 | { 76 | visitor.Visit(this); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /ZenLib.Tests/DebuggingTests.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.Tests 6 | { 7 | using System; 8 | using System.Diagnostics.CodeAnalysis; 9 | using System.Numerics; 10 | using Microsoft.VisualStudio.TestTools.UnitTesting; 11 | using ZenLib; 12 | using ZenLib.Solver; 13 | 14 | /// 15 | /// Tests for the Zen bag type. 16 | /// 17 | [TestClass] 18 | [ExcludeFromCodeCoverage] 19 | public class DebuggingTests 20 | { 21 | /// 22 | /// Test that debugging works with sat. 23 | /// 24 | [TestMethod] 25 | public void TestSolveDebugging() 26 | { 27 | string query = null; 28 | var solverConfig = new SolverConfig { Debug = (x) => query = x.SolverQuery }; 29 | var b = Zen.Symbolic(); 30 | var s = Zen.Symbolic(); 31 | var e = Zen.If(b, "hello", s); 32 | var sol = e.StartsWith("hi").Solve(solverConfig); 33 | Console.WriteLine(query); 34 | Assert.IsTrue(query.Contains("(declare-fun k!2 () String)")); 35 | Assert.IsTrue(query.Contains("(declare-fun k!1 () Bool)")); 36 | Assert.IsTrue(query.Contains("(assert (and (not k!1) (str.prefixof \"hi\" k!2)))")); 37 | } 38 | 39 | /// 40 | /// Test that debugging works with maximize. 41 | /// 42 | [TestMethod] 43 | public void TestMaximizeDebugging() 44 | { 45 | string query = null; 46 | var solverConfig = new SolverConfig { Debug = (x) => query = x.SolverQuery }; 47 | var a = Zen.Symbolic(); 48 | var solution = Zen.Maximize(a, Zen.True(), solverConfig); 49 | Console.WriteLine(query); 50 | Assert.IsTrue(query.Contains("(declare-fun k!1 () (_ BitVec 8))")); 51 | Assert.IsTrue(query.Contains("(assert true)")); 52 | Assert.IsTrue(query.Contains("(maximize k!1)")); 53 | Assert.IsTrue(query.Contains("(check-sat)")); 54 | } 55 | 56 | /// 57 | /// Test that debugging works with minimize. 58 | /// 59 | [TestMethod] 60 | public void TestMinimizeDebugging() 61 | { 62 | string query = null; 63 | var solverConfig = new SolverConfig { Debug = (x) => query = x.SolverQuery }; 64 | var a = Zen.Symbolic(); 65 | var solution = Zen.Minimize(a, Zen.True(), solverConfig); 66 | Console.WriteLine(query); 67 | Assert.IsTrue(query.Contains("(declare-fun k!1 () (_ BitVec 8))")); 68 | Assert.IsTrue(query.Contains("(assert true)")); 69 | Assert.IsTrue(query.Contains("(minimize k!1)")); 70 | Assert.IsTrue(query.Contains("(check-sat)")); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /ZenLib/ModelChecking/Representation/ISymbolicValueVisitor.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.ModelChecking 6 | { 7 | /// 8 | /// Visitor class for symbolic values. 9 | /// 10 | internal interface ISymbolicValueVisitor 11 | { 12 | /// 13 | /// Visit the symbolic boolean type. 14 | /// 15 | TReturn Visit(SymbolicBool v, TParam parameter); 16 | 17 | /// 18 | /// Visit the symbolic bitvec type. 19 | /// 20 | TReturn Visit(SymbolicBitvec v, TParam parameter); 21 | 22 | /// 23 | /// Visit the symbolic char type. 24 | /// 25 | TReturn Visit(SymbolicChar v, TParam parameter); 26 | 27 | /// 28 | /// Visit the symbolic integer type. 29 | /// 30 | TReturn Visit(SymbolicInteger v, TParam parameter); 31 | 32 | /// 33 | /// Visit the symbolic integer type. 34 | /// 35 | TReturn Visit(SymbolicReal v, TParam parameter); 36 | 37 | /// 38 | /// Visit the symbolic string type. 39 | /// 40 | TReturn Visit(SymbolicString v, TParam parameter); 41 | 42 | /// 43 | /// Visit the symbolic class type. 44 | /// 45 | TReturn Visit(SymbolicObject v, TParam parameter); 46 | 47 | /// 48 | /// Visit the symbolic map type. 49 | /// 50 | TReturn Visit(SymbolicMap v, TParam parameter); 51 | 52 | /// 53 | /// Visit the symbolic const map type. 54 | /// 55 | TReturn Visit(SymbolicConstMap v, TParam parameter); 56 | 57 | /// 58 | /// Visit the symbolic list type. 59 | /// 60 | TReturn Visit(SymbolicFSeq v, TParam parameter); 61 | 62 | /// 63 | /// Visit the symbolic list type. 64 | /// 65 | TReturn Visit(SymbolicSeq v, TParam parameter); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /ZenLib/Language/Ast/ZenSeqUnitExpr.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib 6 | { 7 | using System.Diagnostics.CodeAnalysis; 8 | 9 | /// 10 | /// Class representing a sequence unit expression. 11 | /// 12 | internal sealed class ZenSeqUnitExpr : Zen> 13 | { 14 | /// 15 | /// Gets the value expr. 16 | /// 17 | public Zen ValueExpr { get; } 18 | 19 | /// 20 | /// Simplify and create a ZenSeqUnitExpr. 21 | /// 22 | /// The expression. 23 | /// A new Zen expr. 24 | private static Zen> Simplify(Zen e) => new ZenSeqUnitExpr(e); 25 | 26 | /// 27 | /// Create a new ZenSeqUnitExpr. 28 | /// 29 | /// The value expr. 30 | /// The new expr. 31 | public static Zen> Create(Zen valueExpr) 32 | { 33 | Contract.AssertNotNull(valueExpr); 34 | 35 | var flyweight = ZenAstCache, Zen>>.Flyweight; 36 | flyweight.GetOrAdd(valueExpr.Id, valueExpr, Simplify, out var v); 37 | return v; 38 | } 39 | 40 | /// 41 | /// Initializes a new instance of the class. 42 | /// 43 | /// The value expression. 44 | private ZenSeqUnitExpr(Zen valueExpr) 45 | { 46 | this.ValueExpr = valueExpr; 47 | } 48 | 49 | /// 50 | /// Convert the expression to a string. 51 | /// 52 | /// The string representation. 53 | [ExcludeFromCodeCoverage] 54 | public override string ToString() 55 | { 56 | return $"Unit({this.ValueExpr})"; 57 | } 58 | 59 | /// 60 | /// Implementing the visitor interface. 61 | /// 62 | /// The visitor object. 63 | /// The visitor parameter. 64 | /// The visitor parameter type. 65 | /// The visitor return type. 66 | /// A return value. 67 | internal override TReturn Accept(ZenExprVisitor visitor, TParam parameter) 68 | { 69 | return visitor.VisitSeqUnit(this, parameter); 70 | } 71 | 72 | /// 73 | /// Implementing the visitor interface. 74 | /// 75 | /// The visitor object. 76 | internal override void Accept(ZenExprActionVisitor visitor) 77 | { 78 | visitor.Visit(this); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /ZenLib/ModelChecking/Representation/SymbolicObject.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.ModelChecking 6 | { 7 | using System; 8 | using System.Collections.Immutable; 9 | using System.Diagnostics.CodeAnalysis; 10 | using System.Text; 11 | using ZenLib.Solver; 12 | 13 | /// 14 | /// Representation of a symbolic boolean value. 15 | /// 16 | internal class SymbolicObject : SymbolicValue 17 | { 18 | /// 19 | /// Gets the type of the object it represents. 20 | /// 21 | public Type ObjectType; 22 | 23 | /// 24 | /// Gets the underlying decision diagram bitvector representation. 25 | /// 26 | public ImmutableSortedDictionary> Fields { get; set; } 27 | 28 | /// 29 | /// Creates a new instance of the class. 30 | /// 31 | /// The object type. 32 | /// The solver. 33 | /// The symbolic values. 34 | public SymbolicObject( 35 | Type objectType, 36 | ISolver solver, 37 | ImmutableSortedDictionary> value) : base(solver) 38 | { 39 | this.ObjectType = objectType; 40 | this.Fields = value; 41 | } 42 | 43 | /// 44 | /// Accept a visitor. 45 | /// 46 | /// The visitor object. 47 | /// The parameter. 48 | /// The return value. 49 | internal override TReturn Accept( 50 | ISymbolicValueVisitor visitor, 51 | TParam parameter) 52 | { 53 | return visitor.Visit(this, parameter); 54 | } 55 | 56 | /// 57 | /// Convert the object to a string. 58 | /// 59 | /// 60 | [ExcludeFromCodeCoverage] 61 | public override string ToString() 62 | { 63 | StringBuilder sb = new StringBuilder(); 64 | sb.Append("{"); 65 | foreach (var kv in this.Fields) 66 | { 67 | sb.Append($"{kv.Key} = {kv.Value}, "); 68 | } 69 | 70 | sb.Append("}"); 71 | return sb.ToString(); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /ZenLib/ModelChecking/InterleavingAnalysis/InterleavingClass.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.ModelChecking 6 | { 7 | using System; 8 | using System.Collections.Immutable; 9 | using System.Diagnostics.CodeAnalysis; 10 | 11 | /// 12 | /// Representation of interleaving information for an object result. 13 | /// 14 | internal class InterleavingClass : InterleavingResult 15 | { 16 | /// 17 | /// Gets the underlying decision diagram bitvector representation. 18 | /// 19 | public ImmutableDictionary Fields { get; set; } 20 | 21 | /// 22 | /// Creates an instance of the class. 23 | /// 24 | /// The mapping from field to interleaving result. 25 | public InterleavingClass(ImmutableDictionary value) : base() 26 | { 27 | this.Fields = value; 28 | } 29 | 30 | /// 31 | /// Gets all the possible variables the result could have. 32 | /// 33 | /// The variables as a set. 34 | [ExcludeFromCodeCoverage] // we never combine classes. 35 | public override ImmutableHashSet GetAllVariables() 36 | { 37 | var variables = ImmutableHashSet.Empty; 38 | foreach (var fieldResultPair in this.Fields) 39 | { 40 | variables = variables.Union(fieldResultPair.Value.GetAllVariables()); 41 | } 42 | 43 | return variables; 44 | } 45 | 46 | /// 47 | /// Unions the two interleaving results. 48 | /// 49 | /// A new interleaving result. 50 | public override InterleavingResult Union(InterleavingResult other) 51 | { 52 | var o = (InterleavingClass)other; 53 | var result = this.Fields; 54 | foreach (var fieldVariableSetPair in this.Fields) 55 | { 56 | result = result.SetItem(fieldVariableSetPair.Key, fieldVariableSetPair.Value.Union(o.Fields[fieldVariableSetPair.Key])); 57 | } 58 | 59 | return new InterleavingClass(result); 60 | } 61 | 62 | /// 63 | /// Combine variables. 64 | /// 65 | /// The other result. 66 | /// The interleaved objects. 67 | public override void Combine(InterleavingResult other, UnionFind objects) 68 | { 69 | var o = (InterleavingClass)other; 70 | foreach (var field in this.Fields) 71 | { 72 | var r1 = field.Value; 73 | var r2 = o.Fields[field.Key]; 74 | r1.Combine(r2, objects); 75 | } 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /ZenLib.Tests/ReflectionTests.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.Tests 6 | { 7 | using System; 8 | using System.Diagnostics.CodeAnalysis; 9 | using Microsoft.VisualStudio.TestTools.UnitTesting; 10 | using ZenLib; 11 | 12 | /// 13 | /// Tests for reflection. 14 | /// 15 | [TestClass] 16 | [ExcludeFromCodeCoverage] 17 | public class ReflectionTests 18 | { 19 | /// 20 | /// Test that creation works for non-public fields when the constructor has matching parameters. 21 | /// 22 | [TestMethod] 23 | public void TestCreateObjectWithNameParameterConstructor() 24 | { 25 | var fields = new string[] { "X", "Y" }; 26 | var values = new object[] { 1, 2 }; 27 | ReflectionUtilities.CreateInstance(fields, values); 28 | } 29 | 30 | /// 31 | /// Test that creation fails when there is no setter and the parameter names don't match. 32 | /// 33 | [TestMethod] 34 | [ExpectedException(typeof(ZenException))] 35 | public void TestCreateObjectWithInvalidConstructor1() 36 | { 37 | var fields = new string[] { "X", "Z" }; 38 | var values = new object[] { 1, 2 }; 39 | ReflectionUtilities.CreateInstance(fields, values); 40 | } 41 | 42 | /// 43 | /// Test that creation fails when there is no setter and the parameter names don't match. 44 | /// 45 | [TestMethod] 46 | [ExpectedException(typeof(ZenException))] 47 | public void TestCreateObjectWithInvalidConstructor2() 48 | { 49 | var fields = new string[] { "x", "X" }; 50 | var values = new object[] { 1, 2 }; 51 | ReflectionUtilities.CreateInstance(fields, values); 52 | } 53 | 54 | /// 55 | /// Test that zen will create the object through a constructor correctly. 56 | /// 57 | [TestMethod] 58 | public void TestNonPublicFieldsAndProperties() 59 | { 60 | var zf = new ZenConstraint(p => Zen.And(p.GetField("X") == 1, p.GetField("Y") == 2)); 61 | var result = zf.Find(); 62 | Assert.AreEqual(1, result.Value.X); 63 | Assert.AreEqual(2, result.Value.Y); 64 | } 65 | 66 | private struct Point 67 | { 68 | public int X; 69 | 70 | public int Y { get; } 71 | 72 | public Point(int x, int y) 73 | { 74 | X = x; 75 | Y = y; 76 | } 77 | } 78 | 79 | private struct Point2 80 | { 81 | public int x; 82 | 83 | public int X { get; } 84 | 85 | public Point2(int x, int X) 86 | { 87 | this.x = x; 88 | this.X = X; 89 | } 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /ZenLib/Language/Ast/ZenSeqLengthExpr.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib 6 | { 7 | using System.Diagnostics.CodeAnalysis; 8 | using System.Numerics; 9 | 10 | /// 11 | /// Class representing a sequence length expression. 12 | /// 13 | internal sealed class ZenSeqLengthExpr : Zen 14 | { 15 | /// 16 | /// Gets the seq expr. 17 | /// 18 | public Zen> SeqExpr { get; } 19 | 20 | /// 21 | /// Simplify and create a new ZenSeqLengthExpr. 22 | /// 23 | /// The seq expr. 24 | /// The new Zen expr. 25 | private static Zen Simplify(Zen> seqExpr) => new ZenSeqLengthExpr(seqExpr); 26 | 27 | /// 28 | /// Create a new ZenSeqLengthExpr. 29 | /// 30 | /// The seq expr. 31 | /// The new expr. 32 | public static Zen Create(Zen> seqExpr) 33 | { 34 | Contract.AssertNotNull(seqExpr); 35 | 36 | var flyweight = ZenAstCache, Zen>.Flyweight; 37 | flyweight.GetOrAdd(seqExpr.Id, seqExpr, Simplify, out var v); 38 | return v; 39 | } 40 | 41 | /// 42 | /// Initializes a new instance of the class. 43 | /// 44 | /// The seq expression. 45 | private ZenSeqLengthExpr(Zen> seqExpr) 46 | { 47 | this.SeqExpr = seqExpr; 48 | } 49 | 50 | /// 51 | /// Convert the expression to a string. 52 | /// 53 | /// The string representation. 54 | [ExcludeFromCodeCoverage] 55 | public override string ToString() 56 | { 57 | return $"Length({this.SeqExpr})"; 58 | } 59 | 60 | /// 61 | /// Implementing the visitor interface. 62 | /// 63 | /// The visitor object. 64 | /// The visitor parameter. 65 | /// The visitor parameter type. 66 | /// The visitor return type. 67 | /// A return value. 68 | internal override TReturn Accept(ZenExprVisitor visitor, TParam parameter) 69 | { 70 | return visitor.VisitSeqLength(this, parameter); 71 | } 72 | 73 | /// 74 | /// Implementing the visitor interface. 75 | /// 76 | /// The visitor object. 77 | internal override void Accept(ZenExprActionVisitor visitor) 78 | { 79 | visitor.Visit(this); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /ZenLib/ModelChecking/Backend/ModelCheckerFactory.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.ModelChecking 6 | { 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Collections.Immutable; 10 | using DecisionDiagrams; 11 | using Microsoft.Z3; 12 | using ZenLib.Solver; 13 | 14 | /// 15 | /// Model checker factory class. 16 | /// 17 | internal static class ModelCheckerFactory 18 | { 19 | /// 20 | /// Create a model checker. 21 | /// 22 | /// The solver configuration to use. 23 | /// The checking context. 24 | /// The expression to evaluate. 25 | /// The arguements. 26 | /// A new model checker. 27 | internal static IModelChecker CreateModelChecker(SolverConfig config, ModelCheckerContext context, Zen expression, Dictionary arguments) 28 | { 29 | if (config.SolverType == SolverType.DecisionDiagrams) 30 | { 31 | return CreateModelCheckerDD(expression, arguments); 32 | } 33 | 34 | return CreateModelCheckerZ3(context, config.SolverTimeout, config.Debug); 35 | } 36 | 37 | /// 38 | /// Create a model checker based on decision diagrams. 39 | /// 40 | /// The expression. 41 | /// The arguments. 42 | /// A model checker. 43 | private static IModelChecker CreateModelCheckerDD(Zen expression, Dictionary arguments) 44 | { 45 | var heuristic = new InterleavingHeuristicVisitor(); 46 | var args = ImmutableDictionary.Empty.AddRange(arguments); 47 | var mustInterleave = heuristic.GetInterleavedVariables(expression, args); 48 | var manager = new DDManager(); 49 | var solver = new SolverDD(manager, mustInterleave); 50 | solver.Init(); 51 | return new ModelChecker, Variable, DD, BitVector, Unit, Unit, Unit, Unit, Unit>(solver); 52 | } 53 | 54 | /// 55 | /// Create a model checker based on SMT with Z3. 56 | /// 57 | /// The model checker context. 58 | /// A solver timeout parameter. 59 | /// An optional debugging callback. 60 | /// A model checker. 61 | private static IModelChecker CreateModelCheckerZ3(ModelCheckerContext context, TimeSpan? timeout, Action debug) 62 | { 63 | return new ModelChecker(new SolverZ3(context, timeout, debug)); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /ZenLib/Common/Contract.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib 6 | { 7 | using System; 8 | 9 | /// 10 | /// A basic contract/assertion class. 11 | /// 12 | internal static class Contract 13 | { 14 | /// 15 | /// Validate that an argument is true. 16 | /// 17 | /// The argument. 18 | /// An optional message parameter. 19 | public static void Assert(bool obj, string msg = "Assertion failed") 20 | { 21 | if (!obj) 22 | { 23 | throw new ZenException(msg); 24 | } 25 | } 26 | 27 | /// 28 | /// Validate that an argument is not null. 29 | /// 30 | /// The argument. 31 | public static void AssertNotNull(object obj) 32 | { 33 | if (obj is null) 34 | { 35 | throw new ZenException($"Invalid null argument"); 36 | } 37 | } 38 | 39 | /// 40 | /// Validates whether the field or property exists. 41 | /// 42 | /// The object type. 43 | /// The field type. 44 | /// The field or property name. 45 | public static void AssertFieldOrProperty(Type objectType, Type fieldType, string fieldOrPropertyName) 46 | { 47 | var p = objectType.GetPropertyCached(fieldOrPropertyName); 48 | 49 | if (p != null && p.PropertyType != fieldType) 50 | { 51 | throw new ZenException($"Field or property {fieldOrPropertyName} type mismatch with {fieldType} for object with type {objectType}."); 52 | } 53 | 54 | var f = objectType.GetFieldCached(fieldOrPropertyName); 55 | 56 | if (f != null && f.FieldType != fieldType) 57 | { 58 | throw new ZenException($"Field or property {fieldOrPropertyName} type mismatch with {fieldType} for object with type {objectType}."); 59 | } 60 | 61 | if (p == null && f == null) 62 | { 63 | throw new ZenException($"Invalid field or property {fieldOrPropertyName} for object with type {objectType}"); 64 | } 65 | } 66 | 67 | /// 68 | /// Reports a null error in a conversion from a constant to a Zen value. 69 | /// 70 | /// The object that may be null. 71 | /// Description of where the error occurs. 72 | /// The containing type. 73 | public static void AssertNullConversion(object obj, string where, Type type) 74 | { 75 | if (obj is null) 76 | { 77 | throw new ZenException($"Null constant in {where} of type {type} can not be converted to a Zen value."); 78 | } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /ZenLib.Tests/NatTests.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.Tests 6 | { 7 | using System; 8 | using System.Diagnostics.CodeAnalysis; 9 | using Microsoft.VisualStudio.TestTools.UnitTesting; 10 | using ZenLib; 11 | using ZenLib.Tests.Network; 12 | using static ZenLib.Tests.TestHelper; 13 | using static ZenLib.Zen; 14 | 15 | /// 16 | /// Tests for Zen working with classes. 17 | /// 18 | [TestClass] 19 | [ExcludeFromCodeCoverage] 20 | public class NatTests 21 | { 22 | /// 23 | /// A NAT class. 24 | /// 25 | public class Nat 26 | { 27 | /// 28 | /// Gets or sets the rules. 29 | /// 30 | public (uint, uint, uint)[] Rules { get; set; } 31 | } 32 | 33 | private Zen NatMatch(Nat nat, Zen header) 34 | { 35 | return TestHelper.ApplyOrderedRules( 36 | header, 37 | header, 38 | ruleMatch: (l, pkt, i) => MatchNatLine(l, pkt), 39 | ruleAction: (l, pkt, i) => ApplyNatLine(l, pkt), 40 | ruleReturn: (l, pkt, i) => Option.Create(pkt), 41 | nat.Rules); 42 | } 43 | 44 | private Zen MatchNatLine((uint, uint, uint) rule, Zen header) 45 | { 46 | var lo = rule.Item1; 47 | var hi = rule.Item2; 48 | var dstIp = header.GetDstIp().GetValue(); 49 | return And(dstIp >= Constant(lo), dstIp <= Constant(hi)); 50 | } 51 | 52 | private Zen ApplyNatLine((uint, uint, uint) rule, Zen header) 53 | { 54 | var newDstIp = rule.Item3; 55 | return header.WithField("DstIp", Ip.Create(Constant(newDstIp))); 56 | } 57 | 58 | /// 59 | /// Test evaluation for an example NAT. 60 | /// 61 | [TestMethod] 62 | public void TestNatEvaluate() 63 | { 64 | var rules = new ValueTuple[2] { (0, 10, 99), (11, 20, 100) }; 65 | var nat = new Nat { Rules = rules }; 66 | var function = new ZenFunction(p => NatMatch(nat, p)); 67 | Assert.AreEqual(function.Evaluate(new IpHeader { DstIp = new Ip { Value = 10 } }).DstIp.Value, 99U); 68 | Assert.AreEqual(function.Evaluate(new IpHeader { DstIp = new Ip { Value = 11 } }).DstIp.Value, 100U); 69 | } 70 | 71 | /// 72 | /// Test agreement between verification and evaluation. 73 | /// 74 | [TestMethod] 75 | public void TestNatVerify() 76 | { 77 | var rules = new ValueTuple[2] { (0, 10, 99), (11, 20, 100) }; 78 | var nat = new Nat { Rules = rules }; 79 | CheckAgreement(p => NatMatch(nat, p).GetDstIp().GetValue() == Constant(100)); 80 | CheckAgreement(p => NatMatch(nat, p).GetDstIp().GetValue() == Constant(99)); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /ZenLib.Tests/RouteMapTests.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.Tests 6 | { 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Diagnostics.CodeAnalysis; 10 | using Microsoft.VisualStudio.TestTools.UnitTesting; 11 | using ZenLib; 12 | using ZenLib.Tests.Network; 13 | using static ZenLib.Zen; 14 | 15 | /// 16 | /// Tests for Zen with route maps. 17 | /// 18 | [TestClass] 19 | [ExcludeFromCodeCoverage] 20 | public class RouteMapTests 21 | { 22 | /// 23 | /// Test verification for a route map. 24 | /// 25 | [TestMethod] 26 | public void TestRouteMapVerify() 27 | { 28 | var routeMap = ExampleRouteMap(); 29 | 30 | var timer = System.Diagnostics.Stopwatch.StartNew(); 31 | var function = new ZenFunction, int>>(r => routeMap.ProcessProvenance(r)); 32 | var result = function.Find((route, outputRoute) => outputRoute.Item2() == 3); 33 | var input = result.Value; 34 | var output = function.Evaluate(input); 35 | } 36 | 37 | /// 38 | /// Creates an example route map. 39 | /// 40 | /// 41 | private RouteMap ExampleRouteMap() 42 | { 43 | var line1 = new RouteMapLine 44 | { 45 | PrefixGuard = (0, 0, 32), 46 | CommunityGuard = new List { 5U }, 47 | CommunityAdds = new List { }, 48 | CommunityDeletes = new List { }, 49 | AsPathPrepends = new List { }, 50 | Disposition = Disposition.Deny, 51 | }; 52 | 53 | var line2 = new RouteMapLine 54 | { 55 | PrefixGuard = (0, 16, 32), 56 | CommunityGuard = new List { 4U }, 57 | CommunityAdds = new List { 5U }, 58 | CommunityDeletes = new List { 4U }, 59 | AsPathPrepends = new List { }, 60 | Disposition = Disposition.NextTerm, 61 | }; 62 | 63 | var line3 = new RouteMapLine 64 | { 65 | PrefixGuard = (0, 0, 32), 66 | CommunityGuard = new List { 5U }, 67 | CommunityAdds = new List { }, 68 | CommunityDeletes = new List { }, 69 | AsPathPrepends = new List { 100U, 100U }, 70 | Disposition = Disposition.Allow, 71 | }; 72 | 73 | var line4 = new RouteMapLine 74 | { 75 | PrefixGuard = (0, 0, 32), 76 | CommunityGuard = new List { }, 77 | CommunityAdds = new List { }, 78 | CommunityDeletes = new List { }, 79 | AsPathPrepends = new List { }, 80 | Disposition = Disposition.Deny, 81 | }; 82 | 83 | return new RouteMap { Lines = new List { line1, line2, line3, line4 } }; 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /ZenLib/Language/Ast/ZenCastExpr.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib 6 | { 7 | using System.Diagnostics.CodeAnalysis; 8 | 9 | /// 10 | /// Class representing a cast expression. 11 | /// 12 | internal sealed class ZenCastExpr : Zen 13 | { 14 | /// 15 | /// Gets the source expr. 16 | /// 17 | public Zen SourceExpr { get; } 18 | 19 | /// 20 | /// Simplify and create a new ZenCastExpr expr. 21 | /// 22 | /// The expr to cast. 23 | /// The new expr. 24 | private static Zen Simplify(Zen e) => new ZenCastExpr(e); 25 | 26 | /// 27 | /// Create a new ZenCastExpr. 28 | /// 29 | /// The source expr. 30 | /// The new expr. 31 | public static Zen Create(Zen sourceExpr) 32 | { 33 | Contract.AssertNotNull(sourceExpr); 34 | Contract.Assert(CommonUtilities.IsSafeCast(typeof(TSource), typeof(TTarget)), "Invalid cast"); 35 | 36 | var flyweight = ZenAstCache, Zen>.Flyweight; 37 | flyweight.GetOrAdd(sourceExpr.Id, sourceExpr, Simplify, out var v); 38 | return v; 39 | } 40 | 41 | /// 42 | /// Initializes a new instance of the class. 43 | /// 44 | /// The source expression. 45 | private ZenCastExpr(Zen sourceExpr) 46 | { 47 | this.SourceExpr = sourceExpr; 48 | } 49 | 50 | /// 51 | /// Convert the expression to a string. 52 | /// 53 | /// The string representation. 54 | [ExcludeFromCodeCoverage] 55 | public override string ToString() 56 | { 57 | return $"({this.SourceExpr} as {typeof(TTarget).Name})"; 58 | } 59 | 60 | /// 61 | /// Implementing the visitor interface. 62 | /// 63 | /// The visitor object. 64 | /// The visitor parameter. 65 | /// The visitor parameter type. 66 | /// The visitor return type. 67 | /// A return value. 68 | internal override TReturn Accept(ZenExprVisitor visitor, TParam parameter) 69 | { 70 | return visitor.VisitCast(this, parameter); 71 | } 72 | 73 | /// 74 | /// Implementing the visitor interface. 75 | /// 76 | /// The visitor object. 77 | internal override void Accept(ZenExprActionVisitor visitor) 78 | { 79 | visitor.Visit(this); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /ZenLib/DataTypes/UInt.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib 6 | { 7 | using System; 8 | 9 | /// 10 | /// A class representing a fixed bit size integer with unsigned semantics. 11 | /// 12 | public class UInt : Bitvec 13 | { 14 | /// 15 | /// Creates a new instance of the class. 16 | /// 17 | /// The bytes in Big Endian. 18 | public UInt(byte[] bytes) : base(bytes) 19 | { 20 | } 21 | 22 | /// 23 | /// Creates a new instance of the class. 24 | /// 25 | /// The value. 26 | public UInt(long value) : base(value) 27 | { 28 | } 29 | 30 | /// 31 | /// Compute the bitwise and of two integers. 32 | /// 33 | /// The other integer. 34 | /// 35 | public UInt BitwiseAnd(UInt other) 36 | { 37 | Contract.AssertNotNull(other); 38 | return new UInt(base.BitwiseAndBytes(other)); 39 | } 40 | 41 | /// 42 | /// Compute the bitwise and of two integers. 43 | /// 44 | /// The other integer. 45 | /// 46 | public UInt BitwiseOr(UInt other) 47 | { 48 | Contract.AssertNotNull(other); 49 | return new UInt(base.BitwiseOrBytes(other)); 50 | } 51 | 52 | /// 53 | /// Compute the bitwise and of two integers. 54 | /// 55 | /// The other integer. 56 | /// 57 | public UInt BitwiseXor(UInt other) 58 | { 59 | Contract.AssertNotNull(other); 60 | return new UInt(base.BitwiseXorBytes(other)); 61 | } 62 | 63 | /// 64 | /// Compute the bitwise negation of an integer. 65 | /// 66 | /// The negated integer. 67 | public UInt BitwiseNot() 68 | { 69 | return new UInt(base.BitwiseNotBytes()); 70 | } 71 | 72 | /// 73 | /// Adds the integer with another of the same size. 74 | /// Wraps around on overflow. 75 | /// 76 | /// The other integer. 77 | /// The added integer. 78 | public UInt Add(UInt other) 79 | { 80 | Contract.AssertNotNull(other); 81 | return new UInt(base.AddBytes(other)); 82 | } 83 | 84 | /// 85 | /// Subtracts an integer from this integer. 86 | /// Wraps around on overflow. 87 | /// 88 | /// The other integer. 89 | /// The subtracted integer. 90 | public UInt Subtract(UInt other) 91 | { 92 | Contract.AssertNotNull(other); 93 | return new UInt(base.SubtractBytes(other)); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /ZenLib/ModelChecking/InterleavingAnalysis/InterleavingSet.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.ModelChecking 6 | { 7 | using System.Collections.Immutable; 8 | using System.Linq; 9 | 10 | /// 11 | /// Representation of interleaving information for some base type. 12 | /// 13 | internal class InterleavingSet : InterleavingResult 14 | { 15 | /// 16 | /// The set of possible variables. 17 | /// 18 | public ImmutableHashSet Variables { get; } 19 | 20 | /// 21 | /// Creates a new instance of the class. 22 | /// 23 | /// The set of variables. 24 | public InterleavingSet(ImmutableHashSet variables) : base() 25 | { 26 | this.Variables = variables; 27 | } 28 | 29 | /// 30 | /// Gets all the possible variables the result could have. 31 | /// 32 | /// The variables as a set. 33 | public override ImmutableHashSet GetAllVariables() 34 | { 35 | return this.Variables; 36 | } 37 | 38 | /// 39 | /// Unions the two interleaving results. 40 | /// 41 | /// A new interleaving result. 42 | public override InterleavingResult Union(InterleavingResult other) 43 | { 44 | var o = (InterleavingSet)other; 45 | return new InterleavingSet(this.Variables.Union(o.Variables)); 46 | } 47 | 48 | /// 49 | /// Combine variables. 50 | /// 51 | /// The other result. 52 | /// The interleaved objects. 53 | public override void Combine(InterleavingResult other, UnionFind objects) 54 | { 55 | var o = (InterleavingSet)other; 56 | var variableSet1 = this.GetAllVariables(); 57 | var variableSet2 = o.GetAllVariables(); 58 | 59 | if (IsBoolVariableSet(variableSet1) || IsBoolVariableSet(variableSet2)) 60 | { 61 | return; 62 | } 63 | 64 | foreach (var variable1 in variableSet1) 65 | { 66 | foreach (var variable2 in variableSet2) 67 | { 68 | var type1 = variable1.GetType().GetGenericArgumentsCached()[0]; 69 | var type2 = variable2.GetType().GetGenericArgumentsCached()[0]; 70 | 71 | if (type1 == type2) 72 | { 73 | objects.Union(variable1, variable2); 74 | } 75 | } 76 | } 77 | } 78 | 79 | /// 80 | /// Determines if a set of variables is comprised only of boolean values, which do not need interleaving. 81 | /// 82 | /// The set of variables. 83 | /// True or false. 84 | private bool IsBoolVariableSet(ImmutableHashSet variableSet) 85 | { 86 | return variableSet.All(x => typeof(Zen).IsAssignableFrom(x.GetType())); 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /ZenLib/Language/Ast/ZenBitwiseNotExpr.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib 6 | { 7 | using System.Diagnostics.CodeAnalysis; 8 | 9 | /// 10 | /// Class representing a BitwiseNot expression. 11 | /// 12 | internal sealed class ZenBitwiseNotExpr : Zen 13 | { 14 | /// 15 | /// Gets the expression. 16 | /// 17 | internal Zen Expr { get; } 18 | 19 | /// 20 | /// Simplify and create a new ZenBitwiseNot expr. 21 | /// 22 | /// The expr to bitwise negate. 23 | /// The new expr. 24 | private static Zen Simplify(Zen e) 25 | { 26 | var x = ReflectionUtilities.GetConstantIntegerValue(e); 27 | 28 | if (x.HasValue) 29 | { 30 | return ReflectionUtilities.CreateConstantIntegerValue(~x.Value); 31 | } 32 | 33 | if (e is ZenBitwiseNotExpr y) 34 | { 35 | return y.Expr; 36 | } 37 | 38 | return new ZenBitwiseNotExpr(e); 39 | } 40 | 41 | /// 42 | /// Create a new ZenBitwiseNot expr. 43 | /// 44 | /// 45 | /// 46 | public static Zen Create(Zen expr) 47 | { 48 | Contract.AssertNotNull(expr); 49 | Contract.Assert(ReflectionUtilities.IsFiniteIntegerType(typeof(T))); 50 | 51 | var flyweight = ZenAstCache, Zen>.Flyweight; 52 | flyweight.GetOrAdd(expr.Id, expr, Simplify, out var value); 53 | return value; 54 | } 55 | 56 | /// 57 | /// Initializes a new instance of the class. 58 | /// 59 | /// The expression. 60 | private ZenBitwiseNotExpr(Zen expr) 61 | { 62 | this.Expr = expr; 63 | } 64 | 65 | /// 66 | /// Convert the expression to a string. 67 | /// 68 | /// The string representation. 69 | [ExcludeFromCodeCoverage] 70 | public override string ToString() 71 | { 72 | return $"~({this.Expr})"; 73 | } 74 | 75 | /// 76 | /// Implementing the visitor interface. 77 | /// 78 | /// The visitor object. 79 | /// The visitor parameter. 80 | /// The visitor parameter type. 81 | /// The visitor return type. 82 | /// A return value. 83 | internal override TReturn Accept(ZenExprVisitor visitor, TParam parameter) 84 | { 85 | return visitor.VisitBitwiseNot(this, parameter); 86 | } 87 | 88 | /// 89 | /// Implementing the visitor interface. 90 | /// 91 | /// The visitor object. 92 | internal override void Accept(ZenExprActionVisitor visitor) 93 | { 94 | visitor.Visit(this); 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /ZenLib/TransitionSystem/LTL/LTL.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib.TransitionSystem 6 | { 7 | using System; 8 | 9 | /// 10 | /// A temporal logic specification over states of a given type. 11 | /// 12 | public abstract class LTL 13 | { 14 | /// 15 | /// Convert the spec to negated normal form. 16 | /// 17 | /// A spec in nnf. 18 | internal abstract LTL Nnf(); 19 | 20 | /// 21 | /// Encode the loop-free condition. 22 | /// 23 | /// The symbolic states. 24 | /// The current index. 25 | /// Variables for whether at a loop start. 26 | /// Variables for whehter in a loop. 27 | internal abstract Zen Encode(Zen[] states, Zen[] loopStart, Zen[] inLoop, int i); 28 | } 29 | 30 | /// 31 | /// Smart constructors for building specs. 32 | /// 33 | public static class LTL 34 | { 35 | /// 36 | /// A base predicate. 37 | /// 38 | /// The spec for the state. 39 | /// The new spec. 40 | public static LTL Predicate(Func, Zen> spec) 41 | { 42 | return new Predicate { Function = spec }; 43 | } 44 | 45 | /// 46 | /// The 'not' of a spec. 47 | /// 48 | /// The spec. 49 | /// The new spec. 50 | public static LTL Not(LTL spec) 51 | { 52 | return new Not { Formula = spec }; 53 | } 54 | 55 | /// 56 | /// The 'and' of a spec. 57 | /// 58 | /// The first spec. 59 | /// The second spec. 60 | /// The new spec. 61 | public static LTL And(LTL spec1, LTL spec2) 62 | { 63 | return new And { Formula1 = spec1, Formula2 = spec2 }; 64 | } 65 | 66 | /// 67 | /// The 'or' of a spec. 68 | /// 69 | /// The first spec. 70 | /// The second spec. 71 | /// The new spec. 72 | public static LTL Or(LTL spec1, LTL spec2) 73 | { 74 | return new Or { Formula1 = spec1, Formula2 = spec2 }; 75 | } 76 | 77 | /// 78 | /// The 'always' of a spec. 79 | /// 80 | /// The spec. 81 | /// The new spec. 82 | public static LTL Always(LTL spec) 83 | { 84 | return new Always { Formula = spec }; 85 | } 86 | 87 | /// 88 | /// The 'eventually' of a spec. 89 | /// 90 | /// The spec. 91 | /// The new spec. 92 | public static LTL Eventually(LTL spec) 93 | { 94 | return new Eventually { Formula = spec }; 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /ZenLib/Regex/Ast/RegexRangeExpr.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib 6 | { 7 | using System; 8 | using System.Diagnostics.CodeAnalysis; 9 | 10 | /// 11 | /// Class representing a Regex single char expression. 12 | /// 13 | internal sealed class RegexRangeExpr : Regex 14 | { 15 | /// 16 | /// Static creation function for hash consing. 17 | /// 18 | private static Func<(T, T), Regex> createFunc = (v) => Simplify(v.Item1, v.Item2); 19 | 20 | /// 21 | /// Hash cons table for Regex terms. 22 | /// 23 | private static Flyweight<(T, T), Regex> hashConsTable = new Flyweight<(T, T), Regex>(); 24 | 25 | /// 26 | /// Gets the first Regex expression. 27 | /// 28 | internal CharRange CharacterRange { get; } 29 | 30 | /// 31 | /// Simplify a new RegexRangeExpr. 32 | /// 33 | /// The low character value. 34 | /// The high character value. 35 | /// The new Regex expr. 36 | private static Regex Simplify(T low, T high) 37 | { 38 | var range = new CharRange(low, high); 39 | 40 | if (range.IsEmpty()) 41 | { 42 | return RegexEmptyExpr.Instance; 43 | } 44 | 45 | return new RegexRangeExpr(range); 46 | } 47 | 48 | /// 49 | /// Creates a new RegexRangeExpr. 50 | /// 51 | /// The low character value. 52 | /// The high character value. 53 | /// The new Regex expr. 54 | public static Regex Create(T low, T high) 55 | { 56 | var key = (low, high); 57 | hashConsTable.GetOrAdd(key, key, createFunc, out var v); 58 | return v; 59 | } 60 | 61 | /// 62 | /// Initializes a new instance of the class. 63 | /// 64 | /// The character range. 65 | private RegexRangeExpr(CharRange range) 66 | { 67 | this.CharacterRange = range; 68 | } 69 | 70 | /// 71 | /// Convert the expression to a string. 72 | /// 73 | /// The string representation. 74 | [ExcludeFromCodeCoverage] 75 | public override string ToString() 76 | { 77 | return $"Char({this.CharacterRange})"; 78 | } 79 | 80 | /// 81 | /// Implementing the visitor interface. 82 | /// 83 | /// The visitor object. 84 | /// The visitor parameter. 85 | /// The visitor parameter type. 86 | /// The visitor return type. 87 | /// A return value. 88 | internal override TReturn Accept(IRegexExprVisitor visitor, TParam parameter) 89 | { 90 | return visitor.Visit(this, parameter); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /ZenLib/Language/Ast/ZenSeqRegexExpr.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib 6 | { 7 | using System.Diagnostics.CodeAnalysis; 8 | 9 | /// 10 | /// Class representing a seq regex match expression. 11 | /// 12 | internal sealed class ZenSeqRegexExpr : Zen 13 | { 14 | /// 15 | /// Gets the seq expression. 16 | /// 17 | internal Zen> SeqExpr { get; } 18 | 19 | /// 20 | /// Gets the Regex expression. 21 | /// 22 | internal Regex Regex { get; } 23 | 24 | /// 25 | /// Simplify and create a ZenSeqRegexExpr. 26 | /// 27 | /// The arguments. 28 | /// The new Zen expr. 29 | public static Zen Simplify((Zen> e1, Regex e2) args) => new ZenSeqRegexExpr(args.e1, args.e2); 30 | 31 | /// 32 | /// Create a new ZenSeqRegexExpr. 33 | /// 34 | /// The seq expr. 35 | /// The Regex expr. 36 | /// 37 | public static Zen Create(Zen> expr1, Regex expr2) 38 | { 39 | Contract.AssertNotNull(expr1); 40 | Contract.AssertNotNull(expr2); 41 | 42 | var key = (expr1.Id, expr2.Id); 43 | var flyweight = ZenAstCache, Zen>.Flyweight; 44 | flyweight.GetOrAdd(key, (expr1, expr2), Simplify, out var value); 45 | return value; 46 | } 47 | 48 | /// 49 | /// Initializes a new instance of the class. 50 | /// 51 | /// The seq expression. 52 | /// The Regex expression. 53 | private ZenSeqRegexExpr(Zen> seqExpr, Regex regex) 54 | { 55 | this.SeqExpr = seqExpr; 56 | this.Regex = regex; 57 | } 58 | 59 | /// 60 | /// Convert the expression to a string. 61 | /// 62 | /// The string representation. 63 | [ExcludeFromCodeCoverage] 64 | public override string ToString() 65 | { 66 | return $"InRe({this.SeqExpr}, {this.Regex})"; 67 | } 68 | 69 | /// 70 | /// Implementing the visitor interface. 71 | /// 72 | /// The visitor object. 73 | /// The visitor parameter. 74 | /// The visitor parameter type. 75 | /// The visitor return type. 76 | /// A return value. 77 | internal override TReturn Accept(ZenExprVisitor visitor, TParam parameter) 78 | { 79 | return visitor.VisitSeqRegex(this, parameter); 80 | } 81 | 82 | /// 83 | /// Implementing the visitor interface. 84 | /// 85 | /// The visitor object. 86 | internal override void Accept(ZenExprActionVisitor visitor) 87 | { 88 | visitor.Visit(this); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /ZenLib/Language/Ast/ZenSeqNthExpr.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib 6 | { 7 | using System.Diagnostics.CodeAnalysis; 8 | using System.Numerics; 9 | 10 | /// 11 | /// Class representing a sequence nth expression. 12 | /// 13 | internal sealed class ZenSeqNthExpr : Zen 14 | { 15 | /// 16 | /// Gets the seq expression. 17 | /// 18 | internal Zen> SeqExpr { get; } 19 | 20 | /// 21 | /// Gets the index expression. 22 | /// 23 | internal Zen IndexExpr { get; } 24 | 25 | /// 26 | /// Simplify and create a ZenSeqNthExpr. 27 | /// 28 | /// The arguments. 29 | /// The new Zen expr. 30 | public static Zen Simplify((Zen> e1, Zen e2) args) => new ZenSeqNthExpr(args.e1, args.e2); 31 | 32 | /// 33 | /// Create a new ZenSeqAtExpr. 34 | /// 35 | /// The seq expr. 36 | /// The index expr. 37 | /// The new Zen expr. 38 | public static Zen Create(Zen> expr1, Zen expr2) 39 | { 40 | Contract.AssertNotNull(expr1); 41 | Contract.AssertNotNull(expr2); 42 | 43 | var key = (expr1.Id, expr2.Id); 44 | var flyweight = ZenAstCache, Zen>.Flyweight; 45 | flyweight.GetOrAdd(key, (expr1, expr2), Simplify, out var value); 46 | return value; 47 | } 48 | 49 | /// 50 | /// Initializes a new instance of the class. 51 | /// 52 | /// The seq expression. 53 | /// The index expression. 54 | private ZenSeqNthExpr(Zen> seqExpr, Zen indexExpr) 55 | { 56 | this.SeqExpr = seqExpr; 57 | this.IndexExpr = indexExpr; 58 | } 59 | 60 | /// 61 | /// Convert the expression to a string. 62 | /// 63 | /// The string representation. 64 | [ExcludeFromCodeCoverage] 65 | public override string ToString() 66 | { 67 | return $"Nth({this.SeqExpr}, {this.IndexExpr})"; 68 | } 69 | 70 | /// 71 | /// Implementing the visitor interface. 72 | /// 73 | /// The visitor object. 74 | /// The visitor parameter. 75 | /// The visitor parameter type. 76 | /// The visitor return type. 77 | /// A return value. 78 | internal override TReturn Accept(ZenExprVisitor visitor, TParam parameter) 79 | { 80 | return visitor.VisitSeqNth(this, parameter); 81 | } 82 | 83 | /// 84 | /// Implementing the visitor interface. 85 | /// 86 | /// The visitor object. 87 | internal override void Accept(ZenExprActionVisitor visitor) 88 | { 89 | visitor.Visit(this); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /ZenLib/Language/Ast/ZenSeqAtExpr.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib 6 | { 7 | using System.Diagnostics.CodeAnalysis; 8 | using System.Numerics; 9 | 10 | /// 11 | /// Class representing a sequence at expression. 12 | /// 13 | internal sealed class ZenSeqAtExpr : Zen> 14 | { 15 | /// 16 | /// Gets the seq expression. 17 | /// 18 | internal Zen> SeqExpr { get; } 19 | 20 | /// 21 | /// Gets the index expression. 22 | /// 23 | internal Zen IndexExpr { get; } 24 | 25 | /// 26 | /// Simplify and create a ZenSeqAtExpr. 27 | /// 28 | /// The arguments. 29 | /// The new Zen expr. 30 | public static Zen> Simplify((Zen> e1, Zen e2) args) => new ZenSeqAtExpr(args.e1, args.e2); 31 | 32 | /// 33 | /// Create a new ZenSeqAtExpr. 34 | /// 35 | /// The seq expr. 36 | /// The index expr. 37 | /// The new Zen expr. 38 | public static Zen> Create(Zen> expr1, Zen expr2) 39 | { 40 | Contract.AssertNotNull(expr1); 41 | Contract.AssertNotNull(expr2); 42 | 43 | var key = (expr1.Id, expr2.Id); 44 | var flyweight = ZenAstCache, Zen>>.Flyweight; 45 | flyweight.GetOrAdd(key, (expr1, expr2), Simplify, out var value); 46 | return value; 47 | } 48 | 49 | /// 50 | /// Initializes a new instance of the class. 51 | /// 52 | /// The seq expression. 53 | /// The index expression. 54 | private ZenSeqAtExpr(Zen> seqExpr, Zen indexExpr) 55 | { 56 | this.SeqExpr = seqExpr; 57 | this.IndexExpr = indexExpr; 58 | } 59 | 60 | /// 61 | /// Convert the expression to a string. 62 | /// 63 | /// The string representation. 64 | [ExcludeFromCodeCoverage] 65 | public override string ToString() 66 | { 67 | return $"At({this.SeqExpr}, {this.IndexExpr})"; 68 | } 69 | 70 | /// 71 | /// Implementing the visitor interface. 72 | /// 73 | /// The visitor object. 74 | /// The visitor parameter. 75 | /// The visitor parameter type. 76 | /// The visitor return type. 77 | /// A return value. 78 | internal override TReturn Accept(ZenExprVisitor visitor, TParam parameter) 79 | { 80 | return visitor.VisitSeqAt(this, parameter); 81 | } 82 | 83 | /// 84 | /// Implementing the visitor interface. 85 | /// 86 | /// The visitor object. 87 | internal override void Accept(ZenExprActionVisitor visitor) 88 | { 89 | visitor.Visit(this); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /ZenLib/Language/Ast/ZenFSeqAddFrontExpr.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib 6 | { 7 | using System.Diagnostics.CodeAnalysis; 8 | 9 | /// 10 | /// Class representing a list add expression. 11 | /// 12 | internal sealed class ZenFSeqAddFrontExpr : Zen> 13 | { 14 | /// 15 | /// Gets the list expr. 16 | /// 17 | public Zen> ListExpr { get; } 18 | 19 | /// 20 | /// Gets the element to add. 21 | /// 22 | public Zen> ElementExpr { get; } 23 | 24 | /// 25 | /// Simplify and create a ZenFSeqAddFrontExpr. 26 | /// 27 | /// The arguments. 28 | /// A new expr. 29 | private static Zen> Simplify((Zen> e1, Zen> e2) args) => new ZenFSeqAddFrontExpr(args.e1, args.e2); 30 | 31 | /// 32 | /// Create a new ZenListAddFrontExpr. 33 | /// 34 | /// The list expr. 35 | /// The element expr. 36 | /// The new expr. 37 | public static Zen> Create(Zen> expr, Zen> element) 38 | { 39 | Contract.AssertNotNull(expr); 40 | Contract.AssertNotNull(element); 41 | 42 | var key = (expr.Id, element.Id); 43 | var flyweight = ZenAstCache, Zen>>.Flyweight; 44 | flyweight.GetOrAdd(key, (expr, element), Simplify, out var value); 45 | return value; 46 | } 47 | 48 | /// 49 | /// Initializes a new instance of the class. 50 | /// 51 | /// The list expression. 52 | /// The expression for the element to add. 53 | private ZenFSeqAddFrontExpr(Zen> expr, Zen> element) 54 | { 55 | this.ListExpr = expr; 56 | this.ElementExpr = element; 57 | } 58 | 59 | /// 60 | /// Convert the expression to a string. 61 | /// 62 | /// The string representation. 63 | [ExcludeFromCodeCoverage] 64 | public override string ToString() 65 | { 66 | return $"Cons({this.ElementExpr}, {this.ListExpr})"; 67 | } 68 | 69 | /// 70 | /// Implementing the visitor interface. 71 | /// 72 | /// The visitor object. 73 | /// The visitor parameter. 74 | /// The visitor parameter type. 75 | /// The visitor return type. 76 | /// A return value. 77 | internal override TReturn Accept(ZenExprVisitor visitor, TParam parameter) 78 | { 79 | return visitor.VisitListAdd(this, parameter); 80 | } 81 | 82 | /// 83 | /// Implementing the visitor interface. 84 | /// 85 | /// The visitor object. 86 | internal override void Accept(ZenExprActionVisitor visitor) 87 | { 88 | visitor.Visit(this); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /ZenLib/Common/FiniteCache.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft. All rights reserved. 3 | // 4 | 5 | namespace ZenLib 6 | { 7 | using System; 8 | using System.Collections.Generic; 9 | 10 | /// 11 | /// Simple cache that holds only a fixed number of entries. 12 | /// 13 | internal class FiniteCache 14 | { 15 | /// 16 | /// The maximum number of elements allowed. 17 | /// 18 | private int maxCount; 19 | 20 | /// 21 | /// Internal cache of values. 22 | /// 23 | private Dictionary cache; 24 | 25 | /// 26 | /// All the entries. 27 | /// 28 | private List entries; 29 | 30 | /// 31 | /// Random number generator for a random eviction policy. 32 | /// 33 | private Random random; 34 | 35 | /// 36 | /// Creates a new instance of the class. 37 | /// 38 | /// 39 | /// The maximum number of elements stored in the cache. A negative number indicates 40 | /// that the cache has no upper limit. 41 | /// 42 | public FiniteCache(int count) 43 | { 44 | this.maxCount = count; 45 | this.cache = count >= 0 ? new Dictionary(count) : new Dictionary(); 46 | this.entries = new List(); 47 | this.random = new Random(0); 48 | } 49 | 50 | /// 51 | /// Gets the number of entries in the cache. 52 | /// 53 | public int Count { get => this.entries.Count; } 54 | 55 | /// 56 | /// Adds a key and value to the cache. Assumes no duplicate key exists 57 | /// and that the user checks with TryGetValue prior to adding. 58 | /// 59 | /// The key to add. 60 | /// The value for the key. 61 | public void Add(TKey key, TValue value) 62 | { 63 | if (this.maxCount == 0) 64 | { 65 | return; 66 | } 67 | 68 | if (this.entries.Count == maxCount) 69 | { 70 | var toEvictIndex = this.random.Next(0, maxCount); 71 | var toEvictKey = this.entries[toEvictIndex]; 72 | this.cache.Remove(toEvictKey); 73 | this.cache[key] = value; 74 | this.entries[toEvictIndex] = key; 75 | } 76 | else 77 | { 78 | this.cache[key] = value; 79 | this.entries.Add(key); 80 | } 81 | } 82 | 83 | /// 84 | /// Try to get a value from the cache. 85 | /// 86 | /// The key to lookup. 87 | /// The value if it exists. 88 | /// Whether the key is in the cache. 89 | public bool TryGetValue(TKey key, out TValue value) 90 | { 91 | if (this.cache.TryGetValue(key, out var v)) 92 | { 93 | value = v; 94 | return true; 95 | } 96 | 97 | value = default(TValue); 98 | return false; 99 | } 100 | } 101 | } --------------------------------------------------------------------------------