<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://bartdesmet.net/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>B# .NET Blog : Microsoft Research</title><link>http://bartdesmet.net/blogs/bart/archive/tags/Microsoft+Research/default.aspx</link><description>Tags: Microsoft Research</description><dc:language>en</dc:language><generator>CommunityServer 2007 (Build: 20423.869)</generator><item><title>LINQ to Z3 – Theorem Solving on Steroids – Part 1</title><link>http://bartdesmet.net/blogs/bart/archive/2009/09/27/linq-to-z3-theorem-solving-on-steroids-part-1.aspx</link><pubDate>Mon, 28 Sep 2009 06:55:59 GMT</pubDate><guid isPermaLink="false">863c5522-913f-4a64-ac0a-bd5f05abad0f:14829</guid><dc:creator>bart</dc:creator><slash:comments>8</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://bartdesmet.net/blogs/bart/rsscomments.aspx?PostID=14829</wfw:commentRss><comments>http://bartdesmet.net/blogs/bart/archive/2009/09/27/linq-to-z3-theorem-solving-on-steroids-part-1.aspx#comments</comments><description>&lt;h1&gt;Introduction&lt;/h1&gt;  &lt;p&gt;It’s &lt;a href="http://community.bartdesmet.net/blogs/bart/archive/2009/04/19/linq-to-z3-theorem-solving-on-steroids-part-0.aspx"&gt;way too long ago&lt;/a&gt; I wrote about this side-project of mine, as I got side-tracked by other stuff both inside and outside the realm of LINQ (more about that some other time around). Last time, I showed how to put “the query pattern” to our hand by providing an implementation for the Where operator on top of some Theorem&amp;lt;T&amp;gt; type. Let’s recap that to set the scene:&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre class="code"&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color:green;"&gt;Strongly-typed theorem type for use with LINQ syntax.
&lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;typeparam name=&amp;quot;T&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Enviroment type over which the theorem is defined.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
&lt;/span&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Theorem&lt;/span&gt;&amp;lt;T&amp;gt; : &lt;span style="color:#2b91af;"&gt;Theorem
&lt;/span&gt;{&lt;br /&gt;    …

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Where query operator, used to add constraints to the theorem.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;constraint&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Theorem constraint expression.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Theorem with the new constraint applied.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Theorem&lt;/span&gt;&amp;lt;T&amp;gt; Where(&lt;span style="color:#2b91af;"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;T, &lt;span style="color:blue;"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; constraint)
    {
        &lt;span style="color:blue;"&gt;return new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Theorem&lt;/span&gt;&amp;lt;T&amp;gt;(&lt;span style="color:blue;"&gt;base&lt;/span&gt;.Context, &lt;span style="color:blue;"&gt;base&lt;/span&gt;.Constraints.Concat(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;LambdaExpression&lt;/span&gt;&amp;gt; { constraint }));
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Solves the theorem.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Environment type instance with properties set to theorem-satisfying values.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;T Solve()
    {
        &lt;span style="color:blue;"&gt;return base&lt;/span&gt;.Solve&amp;lt;T&amp;gt;();
    }
}&lt;/pre&gt;
  &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;We explained how the non-generic base type keeps track of a set of constraints that have been declared by the user through use of the where query operator, turned into expression trees by the Where signature’s first parameter. This allows us to define constraints in a manner that’s easy on the eye:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;using &lt;/span&gt;(&lt;span style="color:blue;"&gt;var &lt;/span&gt;ctx = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Z3Context&lt;/span&gt;())
{
    ctx.Log = &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.Out;

    &lt;span style="color:blue;"&gt;var &lt;/span&gt;theo = &lt;span style="color:blue;"&gt;from &lt;/span&gt;t &lt;span style="color:blue;"&gt;in &lt;/span&gt;ctx.NewTheorem&amp;lt;&lt;span style="color:#2b91af;"&gt;Symbols&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt;&amp;gt;()
               &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.X1 - t.X2 &amp;gt;= 1
               &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.X1 - t.X2 &amp;lt;= 3
               &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.X1 == (2 * t.X3) + t.X5
               &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.X3 == t.X5
               &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.X2 == 6 * t.X4
               &lt;span style="color:blue;"&gt;select &lt;/span&gt;t;
    
    &lt;span style="color:blue;"&gt;var &lt;/span&gt;result = theo.Solve();
    &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(result);
}&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;The Symbols generic type is one way to create a set of symbols used within the declared theorem’s constraint (and to print the result if the constraints can be satisfied).&lt;/p&gt;

&lt;p&gt;From the above you should be able to get an idea about the LambdaExpression instances that are kept in the Theorem&amp;lt;T&amp;gt;’s base type’s instance field, as collected through the successive calls to Where. Remaining question is how to turn the defined theorem into action, something that’s triggered through the call to Solve. This mystery is what we’ll reveal today.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h1&gt;Three steps to solve a theorem&lt;/h1&gt;

&lt;p&gt;LINQ to Z3 is in fact nothing more but a runtime translator of LINQ expression trees into Z3 calls. The Solve method lies at the heart of this translation and acts as the entry-point for the user. It’s similar to the nature of GetEnumerator in a typical LINQ provider, causing a translation of the query’s LINQ expression tree into the underlying query language (e.g. SQL, CAML, etc).&lt;/p&gt;

&lt;p&gt;Three steps take place to make this work:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;First of all, we need to establish an &lt;em&gt;environment&lt;/em&gt; with the theorem’s symbols and inform Z3 about those. In other words, we map things like X1 to a Z3 counterpart, capturing the name and the type of the symbol (e.g. “T1”, int). We keep track of the Z3 targets (in fact those will be IntPtr pointers, see further) so that subsequent phases of the translation can refer to those when asserting constraints.&lt;/li&gt;

  &lt;li&gt;Secondly, constraints expressed through LINQ need to be translated into Z3 constraints, based on the established environment above. We call this phase the &lt;em&gt;assert constraints&lt;/em&gt; phase which is implemented as an expression tree visitor pattern. Here the bulk of the implementation of LINQ to Z3 lives.&lt;/li&gt;

  &lt;li&gt;Finally, Z3 is queried for a model that satisfied the asserted constraints. If such a model exists, it’s still not ready for consumption by the end-user. To expose the solution in a user-friendly way, the symbols from the environment are mapped onto a .NET object that contains the values satisfying the expressed constraints. This phase is referred to as the &lt;em&gt;get solution&lt;/em&gt; phase.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of the above translates into the following implementation of Solve, on the Theorem base class:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color:green;"&gt;Solves the theorem using Z3.
&lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;typeparam name=&amp;quot;T&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Theorem environment type.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
/// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Result of solving the theorem; default(T) if the theorem cannot be satisfied.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color:blue;"&gt;protected &lt;/span&gt;T Solve&amp;lt;T&amp;gt;()
{
    &lt;span style="color:green;"&gt;// TODO: some debugging around issues with proper disposal of native resources…
    // using (Context context = _context.CreateContext())
    &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Context &lt;/span&gt;context = _context.CreateContext();
    {
        &lt;span style="color:blue;"&gt;var &lt;/span&gt;environment = GetEnvironment&amp;lt;T&amp;gt;(context);

        AssertConstraints&amp;lt;T&amp;gt;(context, environment);

        &lt;span style="color:#2b91af;"&gt;Model &lt;/span&gt;model = &lt;span style="color:blue;"&gt;null&lt;/span&gt;;
        &lt;span style="color:blue;"&gt;if &lt;/span&gt;(context.CheckAndGetModel(&lt;span style="color:blue;"&gt;ref &lt;/span&gt;model) != &lt;span style="color:#2b91af;"&gt;LBool&lt;/span&gt;.True)
            &lt;span style="color:blue;"&gt;return default&lt;/span&gt;(T);

        &lt;span style="color:blue;"&gt;return &lt;/span&gt;GetSolution&amp;lt;T&amp;gt;(model, environment);
    }
}&lt;/pre&gt;
  &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;Recall from the previous post that _context is a Z3Context object that wraps the Z3 Config type. All we do there is creating a Z3 Context object which is the Z3 primitive to start defining a theorem on. Let’s have a brief look at what Z3’s Context type provides (simplified):&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;namespace &lt;/span&gt;Microsoft.Z3
{
    &lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Context &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;IDisposable
    &lt;/span&gt;{
        &lt;span style="color:blue;"&gt;public &lt;/span&gt;Context(&lt;span style="color:#2b91af;"&gt;Config &lt;/span&gt;config);

        &lt;span style="color:blue;"&gt;public void &lt;/span&gt;AssertCnstr(&lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;a);&lt;br /&gt;        …
        &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;LBool &lt;/span&gt;Check();
        &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;LBool &lt;/span&gt;CheckAndGetModel(&lt;span style="color:blue;"&gt;ref &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Model &lt;/span&gt;m);&lt;br /&gt;        …
        &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;MkAdd(&lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;arg1, &lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;arg2);
        &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;MkAnd(&lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;arg1, &lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;arg2);
        &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;MkApp(&lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;d, &lt;span style="color:#2b91af;"&gt;IntPtr&lt;/span&gt;[] args);&lt;br /&gt;        …&lt;br /&gt;&lt;span style="color:blue;"&gt;        public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;MkBoolType();&lt;br /&gt;        …&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;MkConst(&lt;span style="color:blue;"&gt;string &lt;/span&gt;s, &lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;ty);&lt;br /&gt;        …
        &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;MkFuncDecl(&lt;span style="color:blue;"&gt;string &lt;/span&gt;s, &lt;span style="color:#2b91af;"&gt;IntPtr&lt;/span&gt;[] domain, &lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;range);&lt;br /&gt;        …
        &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;MkGe(&lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;arg1, &lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;arg2);
        &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;MkGt(&lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;arg1, &lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;arg2);&lt;br /&gt;        …
        &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;MkXor(&lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;t1, &lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;t2);&lt;br /&gt;        …
        &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;Simplify(&lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;a);&lt;br /&gt;        …
    }
}&lt;/pre&gt;
  &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;As you can see, the way to communicate with the Z3 library is through IntPtr objects. Recall the managed Z3 library is a simple wrapper on top of the native library and the “handle” mechanism to represent Z3 objects is surfaced through IntPtr objects (corresponding to pointers ultimately). Various Mk* functions exist to build up expressions that are used to represent constraints. For example, one could write:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#008080"&gt;IntPtr&lt;/font&gt; cA = ctx.MkConst(&lt;font color="#800000"&gt;“a”&lt;/font&gt;, ctx.MkBoolType());

      &lt;br /&gt;&lt;font face="Courier New"&gt;&lt;font color="#008080"&gt;IntPtr&lt;/font&gt; cb&lt;/font&gt; = ctx.MkConst(&lt;font color="#800000"&gt;“b”&lt;/font&gt;, ctx.MkBoolType());

      &lt;br /&gt;&lt;font face="Courier New"&gt;&lt;font color="#008080"&gt;IntPtr&lt;/font&gt; &lt;/font&gt;aAndb = ctx.MkAnd(cA, cB);

      &lt;br /&gt;ctx.AssertCnstr(aAndb);&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This asserts the constraint “a &amp;amp;&amp;amp; b” (in C# lingo), where a and b are Boolean values, to the Z3 context. Ultimately we can call CheckAndGetModel to see whether the constraints can be satisfied, and if so a Model is passed back to us:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:#2b91af;"&gt;Model &lt;/span&gt;model = &lt;span style="color:blue;"&gt;null&lt;/span&gt;;
&lt;span style="color:blue;"&gt;if &lt;/span&gt;(context.CheckAndGetModel(&lt;span style="color:blue;"&gt;ref &lt;/span&gt;model) != &lt;span style="color:#2b91af;"&gt;LBool&lt;/span&gt;.True)&lt;br /&gt;   …&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;To consume the model, we can use the Model type in various ways:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;namespace &lt;/span&gt;Microsoft.Z3
{
    &lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Model &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;IDisposable
    &lt;/span&gt;{
        &lt;span style="color:blue;"&gt;public void &lt;/span&gt;Display(&lt;span style="color:#2b91af;"&gt;TextWriter &lt;/span&gt;w);
        &lt;span style="color:blue;"&gt;public void &lt;/span&gt;Display(&lt;span style="color:#2b91af;"&gt;TextWriter &lt;/span&gt;w, &lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;v);&lt;br /&gt;        …
        &lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;Eval(&lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;__p1);&lt;br /&gt;        …
        &lt;span style="color:blue;"&gt;public bool &lt;/span&gt;GetBoolValueBool(&lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;v);&lt;br /&gt;        …
    }
}&lt;/pre&gt;
  &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;Either we print the whole model or we evaluate expressions against the Model (amongst other options). Below is a sample of how a and b can be retrieved. Notice how cA and cB are used again to query the model:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;bool &lt;/font&gt;a = model.GetBoolValueBool(model.Eval(cA));

      &lt;br /&gt;&lt;font color="#0000ff"&gt;bool &lt;/font&gt;b = model.GetBoolValueBool(model.Eval(cB));&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;All of the above is obviously a code fragment specialized to solve the constraint “a &amp;amp;&amp;amp; b”, getting the result back as two Booleans. In LINQ to Z3 we need to generalize the steps above:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;We’ll introduce an environment that maps every symbol from the theorem onto the underlying IntPtr retrieved from calling MkConst.&lt;/li&gt;

  &lt;li&gt;We’ll visit the expression trees that declare the constraints, generating Z3 expressions (e.g. via MkAnd) and asserting them on the Context.&lt;/li&gt;

  &lt;li&gt;We’ll extract the model’s values for the bindings in the environment to instantiate an object representing the solution (if any).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s start by looking at the code to establish an environment.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h1&gt;Taking care of the environment&lt;/h1&gt;

&lt;p&gt;First we need to establish the environment from the T generic parameter type. E.g. in the aforementioned sample Symbols&amp;lt;…&amp;gt; is our starting point:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font face="Courier new"&gt;&lt;span style="color:blue;"&gt;from &lt;/span&gt;t &lt;span style="color:blue;"&gt;in &lt;/span&gt;ctx.NewTheorem&amp;lt;&lt;strong&gt;&lt;u&gt;&lt;span style="color:#2b91af;"&gt;Symbols&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt;&lt;/u&gt;&lt;/strong&gt;&amp;gt;() … &lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But the user could equally well use different means to establish a bag of symbols to write a theorem against, e.g.:&lt;/p&gt;

&lt;blockquote&gt;&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;from &lt;/span&gt;t &lt;span style="color:blue;"&gt;in &lt;/span&gt;ctx.NewTheorem(&lt;strong&gt;&lt;u&gt;&lt;span style="color:blue;"&gt;new &lt;/span&gt;{ x = &lt;span style="color:blue;"&gt;default&lt;/span&gt;(&lt;span style="color:blue;"&gt;bool&lt;/span&gt;), y = &lt;span style="color:blue;"&gt;default&lt;/span&gt;(&lt;span style="color:blue;"&gt;bool&lt;/span&gt;) }&lt;/u&gt;&lt;/strong&gt;) …&lt;/pre&gt;
  &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;We need to let Z3 know what the types are of the symbols we’re using here. Obviously we’re going to use reflection to extract this information as shown below:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color:green;"&gt;Maps the properties on the theorem environment type to Z3 handles for bound variables.
&lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;typeparam name=&amp;quot;T&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Theorem environment type to create a mapping table for.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
/// &amp;lt;param name=&amp;quot;context&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Z3 context.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Environment mapping table from .NET properties onto Z3 handles.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color:blue;"&gt;private static &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;PropertyInfo&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;IntPtr&lt;/span&gt;&amp;gt; GetEnvironment&amp;lt;T&amp;gt;(&lt;span style="color:#2b91af;"&gt;Context &lt;/span&gt;context)
{
    &lt;span style="color:blue;"&gt;var &lt;/span&gt;environment = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;PropertyInfo&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;IntPtr&lt;/span&gt;&amp;gt;();

    &lt;span style="color:green;"&gt;//
    // All public properties are considered part of the theorem&amp;#39;s environment.
    // Notice we can&amp;#39;t require custom attribute tagging if we want the user to be able to
    // use anonymous types as a convenience solution.
    //
    &lt;/span&gt;&lt;span style="color:blue;"&gt;foreach &lt;/span&gt;(&lt;span style="color:blue;"&gt;var &lt;/span&gt;parameter &lt;span style="color:blue;"&gt;in typeof&lt;/span&gt;(T).GetProperties(&lt;span style="color:#2b91af;"&gt;BindingFlags&lt;/span&gt;.Public | &lt;span style="color:#2b91af;"&gt;BindingFlags&lt;/span&gt;.Instance))
    {
        &lt;span style="color:green;"&gt;//
        // Normalize types when facing Z3. Theorem variable type mappings allow for strong
        // typing within the theorem, while underlying variable representations are Z3-
        // friendly types.
        //
        &lt;/span&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;parameterType = parameter.PropertyType;
        &lt;span style="color:blue;"&gt;var &lt;/span&gt;parameterTypeMapping = (&lt;span style="color:#2b91af;"&gt;TheoremVariableTypeMappingAttribute&lt;/span&gt;)parameterType.GetCustomAttributes(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;TheoremVariableTypeMappingAttribute&lt;/span&gt;), &lt;span style="color:blue;"&gt;false&lt;/span&gt;).SingleOrDefault();
        &lt;span style="color:blue;"&gt;if &lt;/span&gt;(parameterTypeMapping != &lt;span style="color:blue;"&gt;null&lt;/span&gt;)
            parameterType = parameterTypeMapping.RegularType;

        &lt;span style="color:green;"&gt;//
        // Map the environment onto Z3-compatible types.
        //
        &lt;/span&gt;&lt;span style="color:blue;"&gt;if &lt;/span&gt;(parameterType == &lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:blue;"&gt;bool&lt;/span&gt;))
            environment.Add(parameter, context.MkConst(parameter.Name, context.MkBoolType()));
        &lt;span style="color:blue;"&gt;else if &lt;/span&gt;(parameterType == &lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:blue;"&gt;int&lt;/span&gt;))
            environment.Add(parameter, context.MkConst(parameter.Name, context.MkIntType()));
        &lt;span style="color:blue;"&gt;else
            throw new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;NotSupportedException&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Unsupported parameter type for &amp;quot; &lt;/span&gt;+ parameter.Name + &lt;span style="color:#a31515;"&gt;&amp;quot;.&amp;quot;&lt;/span&gt;);
    }

    &lt;span style="color:blue;"&gt;return &lt;/span&gt;environment;
}&lt;/pre&gt;
  &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;To understand the above, start from the method’s contract: given a Z3 context, we’re going to return a dictionary that maps PropertyInfo objects onto IntPtr objects representing the symbols introduced on the Z3 context. The code is fairly straightforward to understand and only cares about properties (though one could extend it to allow fields as well). Ignore the TheoremVariableTypeMapping part, which can be dropped from the code for the time being, which will be explained in subsequent posts. Notice we only support Z3’s Bool and Int types.&lt;/p&gt;

&lt;p&gt;This was easy, wasn’t it? Next, the meat of the translator: translating and asserting constraints.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h1&gt;Asserting constraints&lt;/h1&gt;

&lt;p&gt;Asserting the constraints from the LINQ expression trees onto Z3 constraints is the next, and most complicated, step. The entry-point to the method responsible for this looks as follows:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color:green;"&gt;Asserts the theorem constraints on the Z3 context.
&lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&amp;quot;context&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Z3 context.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;environment&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Environment with bindings of theorem variables to Z3 handles.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;typeparam name=&amp;quot;T&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Theorem environment type.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
&lt;/span&gt;&lt;span style="color:blue;"&gt;private void &lt;/span&gt;AssertConstraints&amp;lt;T&amp;gt;(&lt;span style="color:#2b91af;"&gt;Context &lt;/span&gt;context, &lt;span style="color:#2b91af;"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;PropertyInfo&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;IntPtr&lt;/span&gt;&amp;gt; environment)
{
    &lt;span style="color:blue;"&gt;var &lt;/span&gt;constraints = _constraints;

    &lt;span style="color:green;"&gt;//
    // Global rewwriter registered?
    //
    &lt;/span&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;rewriterAttr = (&lt;span style="color:#2b91af;"&gt;TheoremGlobalRewriterAttribute&lt;/span&gt;)&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(T).GetCustomAttributes(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;TheoremGlobalRewriterAttribute&lt;/span&gt;), &lt;span style="color:blue;"&gt;false&lt;/span&gt;).SingleOrDefault();
    &lt;span style="color:blue;"&gt;if &lt;/span&gt;(rewriterAttr != &lt;span style="color:blue;"&gt;null&lt;/span&gt;)
    {
        &lt;span style="color:green;"&gt;//
        // Make sure the specified rewriter type implements the ITheoremGlobalRewriter.
        //
        &lt;/span&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;rewriterType = rewriterAttr.RewriterType;
        &lt;span style="color:blue;"&gt;if &lt;/span&gt;(!&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;ITheoremGlobalRewriter&lt;/span&gt;).IsAssignableFrom(rewriterType))
            &lt;span style="color:blue;"&gt;throw new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;InvalidOperationException&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Invalid global rewriter type definition. Did you implement ITheoremGlobalRewriter?&amp;quot;&lt;/span&gt;);

        &lt;span style="color:green;"&gt;//
        // Assume a parameterless public constructor to new up the rewriter.
        //
        &lt;/span&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;rewriter = (&lt;span style="color:#2b91af;"&gt;ITheoremGlobalRewriter&lt;/span&gt;)&lt;span style="color:#2b91af;"&gt;Activator&lt;/span&gt;.CreateInstance(rewriterType);

        &lt;span style="color:green;"&gt;//
        // Do the rewrite.
        //
        &lt;/span&gt;constraints = rewriter.Rewrite(constraints);
    }

    &lt;span style="color:green;"&gt;//
    // Visit, assert and log.
    //
    &lt;/span&gt;&lt;span style="color:blue;"&gt;foreach &lt;/span&gt;(&lt;span style="color:blue;"&gt;var &lt;/span&gt;constraint &lt;span style="color:blue;"&gt;in &lt;/span&gt;constraints)
    {
        &lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;c = Visit(context, environment, constraint.Body, constraint.Parameters[0]);
        context.AssertCnstr(c);

        _context.LogWriteLine(context.ToString(c));
    }
}&lt;/pre&gt;
  &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;I’m not holding any information back, so some of the above can be ignored for the time being: mask away all of the code with the word rewriter in it, as it will be explained next time around. (To satisfy your curiosity, rewriters allow to create domain-specific constraint languages, e.g. to solve a Kakuro puzzle.)&lt;/p&gt;

&lt;p&gt;The essence of the code lives in the foreach-loop that translates the lambda expression-based constraints by a call to the Visit method, returning a Z3 expression for the constraint which is subsequently asserted on the Z3 context. Obviously Visit is where all the magic happens. To do so, it gets four parameters:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The Z3 context, to call Mk* functions on during the translation.&lt;/li&gt;

  &lt;li&gt;Our environment, to be able to map occurrences of symbols (expressed as properties) onto the introduced Z3 corresponding objects.&lt;/li&gt;

  &lt;li&gt;Obviously the lambda expression’s body to translate (cf. &lt;font face="Courier New"&gt;&lt;span style="color:#2b91af;"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;T, &lt;span style="color:blue;"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; constraint&lt;/font&gt;).&lt;/li&gt;

  &lt;li&gt;And finally, the lambda expression’s parameter expression object (so that calls on it can be recognized, e.g. &lt;strong&gt;&lt;u&gt;symbols&lt;/u&gt;&lt;/strong&gt; =&amp;gt; … &lt;strong&gt;&lt;u&gt;symbols.&lt;/u&gt;&lt;/strong&gt;X1 …).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On to the visitor now. Before we do so, let’s think a bit about the operations we want to support on constraints: arithmetic (+, -, *, /, %), logic (&amp;amp;&amp;amp;, ||, !) and relational (&amp;lt;, &amp;lt;=, &amp;gt;, &amp;gt;=, ==, !=). There’ll be a few more as we shall see in a minute. As usual with expression trees, lots of switch-statements will be attending the party:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color:green;"&gt;Main visitor method to translate the LINQ expression tree into a Z3 expression handle.
&lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&amp;quot;context&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Z3 context.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;environment&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Environment with bindings of theorem variables to Z3 handles.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;expression&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;LINQ expression tree node to be translated.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;param&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Parameter used to express the constraint on.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Z3 expression handle.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;Visit(&lt;span style="color:#2b91af;"&gt;Context &lt;/span&gt;context, &lt;span style="color:#2b91af;"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;PropertyInfo&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;IntPtr&lt;/span&gt;&amp;gt; environment, &lt;span style="color:#2b91af;"&gt;Expression &lt;/span&gt;expression, &lt;span style="color:#2b91af;"&gt;ParameterExpression &lt;/span&gt;param)
{
    &lt;span style="color:green;"&gt;//
    // Largely table-driven mechanism, providing constructor lambdas to generic Visit*
    // methods, classified by type and arity.
    //
    &lt;/span&gt;&lt;span style="color:blue;"&gt;switch &lt;/span&gt;(expression.NodeType)
    {
        &lt;span style="color:blue;"&gt;case &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ExpressionType&lt;/span&gt;.And:
        &lt;span style="color:blue;"&gt;case &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ExpressionType&lt;/span&gt;.AndAlso:
            &lt;span style="color:blue;"&gt;return &lt;/span&gt;VisitBinary(context, environment, (&lt;span style="color:#2b91af;"&gt;BinaryExpression&lt;/span&gt;)expression, param, (ctx, a, b) =&amp;gt; ctx.MkAnd(a, b));
        &lt;span style="color:blue;"&gt;case &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ExpressionType&lt;/span&gt;.Or:
        &lt;span style="color:blue;"&gt;case &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ExpressionType&lt;/span&gt;.OrElse:
            &lt;span style="color:blue;"&gt;return &lt;/span&gt;VisitBinary(context, environment, (&lt;span style="color:#2b91af;"&gt;BinaryExpression&lt;/span&gt;)expression, param, (ctx, a, b) =&amp;gt; ctx.MkOr(a, b));
        &lt;span style="color:blue;"&gt;case &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ExpressionType&lt;/span&gt;.ExclusiveOr:
            &lt;span style="color:blue;"&gt;return &lt;/span&gt;VisitBinary(context, environment, (&lt;span style="color:#2b91af;"&gt;BinaryExpression&lt;/span&gt;)expression, param, (ctx, a, b) =&amp;gt; ctx.MkXor(a, b));
        &lt;span style="color:blue;"&gt;case &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ExpressionType&lt;/span&gt;.Not:
            &lt;span style="color:blue;"&gt;return &lt;/span&gt;VisitUnary(context, environment, (&lt;span style="color:#2b91af;"&gt;UnaryExpression&lt;/span&gt;)expression, param, (ctx, a) =&amp;gt; ctx.MkNot(a));
        &lt;span style="color:blue;"&gt;case &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ExpressionType&lt;/span&gt;.Negate:
        &lt;span style="color:blue;"&gt;case &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ExpressionType&lt;/span&gt;.NegateChecked:
            &lt;span style="color:blue;"&gt;return &lt;/span&gt;VisitUnary(context, environment, (&lt;span style="color:#2b91af;"&gt;UnaryExpression&lt;/span&gt;)expression, param, (ctx, a) =&amp;gt; ctx.MkUnaryMinus(a));
        &lt;span style="color:blue;"&gt;case &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ExpressionType&lt;/span&gt;.Add:
        &lt;span style="color:blue;"&gt;case &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ExpressionType&lt;/span&gt;.AddChecked:
            &lt;span style="color:blue;"&gt;return &lt;/span&gt;VisitBinary(context, environment, (&lt;span style="color:#2b91af;"&gt;BinaryExpression&lt;/span&gt;)expression, param, (ctx, a, b) =&amp;gt; ctx.MkAdd(a, b));
        &lt;span style="color:blue;"&gt;case &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ExpressionType&lt;/span&gt;.Subtract:
        &lt;span style="color:blue;"&gt;case &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ExpressionType&lt;/span&gt;.SubtractChecked:
            &lt;span style="color:blue;"&gt;return &lt;/span&gt;VisitBinary(context, environment, (&lt;span style="color:#2b91af;"&gt;BinaryExpression&lt;/span&gt;)expression, param, (ctx, a, b) =&amp;gt; ctx.MkSub(a, b));
        &lt;span style="color:blue;"&gt;case &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ExpressionType&lt;/span&gt;.Multiply:
        &lt;span style="color:blue;"&gt;case &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ExpressionType&lt;/span&gt;.MultiplyChecked:
            &lt;span style="color:blue;"&gt;return &lt;/span&gt;VisitBinary(context, environment, (&lt;span style="color:#2b91af;"&gt;BinaryExpression&lt;/span&gt;)expression, param, (ctx, a, b) =&amp;gt; ctx.MkMul(a, b));
        &lt;span style="color:blue;"&gt;case &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ExpressionType&lt;/span&gt;.Divide:
            &lt;span style="color:blue;"&gt;return &lt;/span&gt;VisitBinary(context, environment, (&lt;span style="color:#2b91af;"&gt;BinaryExpression&lt;/span&gt;)expression, param, (ctx, a, b) =&amp;gt; ctx.MkDiv(a, b));
        &lt;span style="color:blue;"&gt;case &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ExpressionType&lt;/span&gt;.Modulo:
            &lt;span style="color:blue;"&gt;return &lt;/span&gt;VisitBinary(context, environment, (&lt;span style="color:#2b91af;"&gt;BinaryExpression&lt;/span&gt;)expression, param, (ctx, a, b) =&amp;gt; ctx.MkRem(a, b));
        &lt;span style="color:blue;"&gt;case &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ExpressionType&lt;/span&gt;.LessThan:
            &lt;span style="color:blue;"&gt;return &lt;/span&gt;VisitBinary(context, environment, (&lt;span style="color:#2b91af;"&gt;BinaryExpression&lt;/span&gt;)expression, param, (ctx, a, b) =&amp;gt; ctx.MkLt(a, b));
        &lt;span style="color:blue;"&gt;case &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ExpressionType&lt;/span&gt;.LessThanOrEqual:
            &lt;span style="color:blue;"&gt;return &lt;/span&gt;VisitBinary(context, environment, (&lt;span style="color:#2b91af;"&gt;BinaryExpression&lt;/span&gt;)expression, param, (ctx, a, b) =&amp;gt; ctx.MkLe(a, b));
        &lt;span style="color:blue;"&gt;case &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ExpressionType&lt;/span&gt;.GreaterThan:
            &lt;span style="color:blue;"&gt;return &lt;/span&gt;VisitBinary(context, environment, (&lt;span style="color:#2b91af;"&gt;BinaryExpression&lt;/span&gt;)expression, param, (ctx, a, b) =&amp;gt; ctx.MkGt(a, b));
        &lt;span style="color:blue;"&gt;case &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ExpressionType&lt;/span&gt;.GreaterThanOrEqual:
            &lt;span style="color:blue;"&gt;return &lt;/span&gt;VisitBinary(context, environment, (&lt;span style="color:#2b91af;"&gt;BinaryExpression&lt;/span&gt;)expression, param, (ctx, a, b) =&amp;gt; ctx.MkGe(a, b));
        &lt;span style="color:blue;"&gt;case &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ExpressionType&lt;/span&gt;.Equal:
            &lt;span style="color:blue;"&gt;return &lt;/span&gt;VisitBinary(context, environment, (&lt;span style="color:#2b91af;"&gt;BinaryExpression&lt;/span&gt;)expression, param, (ctx, a, b) =&amp;gt; ctx.MkEq(a, b));
        &lt;span style="color:blue;"&gt;case &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ExpressionType&lt;/span&gt;.NotEqual:
            &lt;span style="color:blue;"&gt;return &lt;/span&gt;VisitBinary(context, environment, (&lt;span style="color:#2b91af;"&gt;BinaryExpression&lt;/span&gt;)expression, param, (ctx, a, b) =&amp;gt; ctx.MkNot(ctx.MkEq(a, b)));
        &lt;span style="color:blue;"&gt;case &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ExpressionType&lt;/span&gt;.MemberAccess:
            &lt;span style="color:blue;"&gt;return &lt;/span&gt;VisitMember(environment, (&lt;span style="color:#2b91af;"&gt;MemberExpression&lt;/span&gt;)expression, param);
        &lt;span style="color:blue;"&gt;case &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ExpressionType&lt;/span&gt;.Constant:
            &lt;span style="color:blue;"&gt;return &lt;/span&gt;VisitConstant(context, (&lt;span style="color:#2b91af;"&gt;ConstantExpression&lt;/span&gt;)expression);
        &lt;span style="color:blue;"&gt;case &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ExpressionType&lt;/span&gt;.Call:
            &lt;span style="color:blue;"&gt;return &lt;/span&gt;VisitCall(context, environment, (&lt;span style="color:#2b91af;"&gt;MethodCallExpression&lt;/span&gt;)expression, param);
        &lt;span style="color:blue;"&gt;default&lt;/span&gt;:
            &lt;span style="color:blue;"&gt;throw new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;NotSupportedException&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Unsupported expression node type encountered: &amp;quot; &lt;/span&gt;+ expression.NodeType);
    }
}&lt;/pre&gt;
  &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;Notice the above is made as declarative as possible: most expression tree node types are mapped on either unary or binary specialized visitor methods, passing in a lambda expression that acts as the “Z3 constructor”. For example, And (for &amp;amp; in C#) uses a “(ctx, a, b) =&amp;gt; ctx.MkAnd(a, b)” argument. The VisitBinary method will be responsible to recursively translate the left-hand side and right-hand side of the And operation (e.g. x &amp;amp; y, where x and y can be arbitrarily complex BLOCKED EXPRESSION, ultimately feeding the resulting Z3-returned IntPtr objects into the supplied lambda expression.&lt;/p&gt;

&lt;p&gt;Next to the VisitBinary and VisitUnary calls, there are specialized calls for the MemberAccess, Constant and Call expression tree nodes. We’ll defer the discussion of those for a moment and focus on binary and unary calls first:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color:green;"&gt;Visitor method to translate a binary expression.
&lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&amp;quot;context&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Z3 context.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;environment&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Environment with bindings of theorem variables to Z3 handles.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;expression&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Binary expression.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;ctor&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Constructor to combine recursive visitor results.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;param&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Parameter used to express the constraint on.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Z3 expression handle.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;VisitBinary(&lt;span style="color:#2b91af;"&gt;Context &lt;/span&gt;context, &lt;span style="color:#2b91af;"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;PropertyInfo&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;IntPtr&lt;/span&gt;&amp;gt; environment, &lt;span style="color:#2b91af;"&gt;BinaryExpression &lt;/span&gt;expression, &lt;span style="color:#2b91af;"&gt;ParameterExpression &lt;/span&gt;param, &lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Context&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;IntPtr&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;IntPtr&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;IntPtr&lt;/span&gt;&amp;gt; ctor)
{
    &lt;span style="color:blue;"&gt;return &lt;/span&gt;ctor(context, Visit(context, environment, expression.Left, param), Visit(context, environment, expression.Right, param));
}

&lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color:green;"&gt;Visitor method to translate a unary expression.
&lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&amp;quot;context&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Z3 context.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;environment&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Environment with bindings of theorem variables to Z3 handles.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;expression&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Unary expression.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;ctor&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Constructor to combine recursive visitor results.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;param&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Parameter used to express the constraint on.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Z3 expression handle.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;VisitUnary(&lt;span style="color:#2b91af;"&gt;Context &lt;/span&gt;context, &lt;span style="color:#2b91af;"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;PropertyInfo&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;IntPtr&lt;/span&gt;&amp;gt; environment, &lt;span style="color:#2b91af;"&gt;UnaryExpression &lt;/span&gt;expression, &lt;span style="color:#2b91af;"&gt;ParameterExpression &lt;/span&gt;param, &lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Context&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;IntPtr&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;IntPtr&lt;/span&gt;&amp;gt; ctor)
{
    &lt;span style="color:blue;"&gt;return &lt;/span&gt;ctor(context, Visit(context, environment, expression.Operand, param));
}&lt;/pre&gt;
  &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;More documentation than anything else :-). Those methods simply visit the expression’s operands (e.g. Left, Right for a binary expression, Operand for a unary one) recursively. The obtained results, of type IntPtr, are fed into the “ctor” delegate parameter to obtain the final result. Trivial stuff.&lt;/p&gt;

&lt;p&gt;Now the more complicated visitor methods for members, constants and method calls. First, constants:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color:green;"&gt;Visitor method to translate a constant expression.
&lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&amp;quot;context&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Z3 context.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;constant&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Constant expression.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Z3 expression handle.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color:blue;"&gt;private static &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;VisitConstant(&lt;span style="color:#2b91af;"&gt;Context &lt;/span&gt;context, &lt;span style="color:#2b91af;"&gt;ConstantExpression &lt;/span&gt;constant)
{
    &lt;span style="color:blue;"&gt;if &lt;/span&gt;(constant.Type == &lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:blue;"&gt;int&lt;/span&gt;))
        &lt;span style="color:blue;"&gt;return &lt;/span&gt;context.MkNumeral((&lt;span style="color:blue;"&gt;int&lt;/span&gt;)constant.Value, context.MkIntType());
    &lt;span style="color:blue;"&gt;else if &lt;/span&gt;(constant.Type == &lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:blue;"&gt;bool&lt;/span&gt;))
        &lt;span style="color:blue;"&gt;return &lt;/span&gt;(&lt;span style="color:blue;"&gt;bool&lt;/span&gt;)constant.Value ? context.MkTrue() : context.MkFalse();

    &lt;span style="color:blue;"&gt;throw new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;NotSupportedException&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Unsupported constant type.&amp;quot;&lt;/span&gt;);
}&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;This code should be easy enough to understand as well: looking at the type of the constant value, different Z3 calls are made based on the Value property’s value.&lt;/p&gt;

&lt;p&gt;Members get a tiny bit more involved, as that’s where we need to recognize property accesses for symbols. In other words, we need to recognize the &lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color:green;"&gt;Visitor method to translate a member expression.
&lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&amp;quot;environment&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Environment with bindings of theorem variables to Z3 handles.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;member&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Member expression.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;param&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Parameter used to express the constraint on.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Z3 expression handle.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color:blue;"&gt;private static &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;VisitMember(&lt;span style="color:#2b91af;"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;PropertyInfo&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;IntPtr&lt;/span&gt;&amp;gt; environment, &lt;span style="color:#2b91af;"&gt;MemberExpression &lt;/span&gt;member, &lt;span style="color:#2b91af;"&gt;ParameterExpression &lt;/span&gt;param)
{
    &lt;span style="color:green;"&gt;//
    // E.g. Symbols l = ...;
    //      theorem.Where(s =&amp;gt; l.X1)
    //                         ^^
    //
    &lt;/span&gt;&lt;span style="color:blue;"&gt;if &lt;/span&gt;(member.Expression != param)
        &lt;span style="color:blue;"&gt;throw new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;NotSupportedException&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Encountered member access not targeting the constraint parameter.&amp;quot;&lt;/span&gt;);

    &lt;span style="color:green;"&gt;//
    // Only members we allow currently are direct accesses to the theorem&amp;#39;s variables
    // in the environment type. So we just try to find the mapping from the environment
    // bindings table.
    //
    &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;PropertyInfo &lt;/span&gt;property;
    &lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;value;
    &lt;span style="color:blue;"&gt;if &lt;/span&gt;((property = member.Member &lt;span style="color:blue;"&gt;as &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;PropertyInfo&lt;/span&gt;) == &lt;span style="color:blue;"&gt;null
        &lt;/span&gt;|| !environment.TryGetValue(property, &lt;span style="color:blue;"&gt;out &lt;/span&gt;value))
        &lt;span style="color:blue;"&gt;throw new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;NotSupportedException&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Unknown parameter encountered: &amp;quot; &lt;/span&gt;+ member.Member.Name + &lt;span style="color:#a31515;"&gt;&amp;quot;.&amp;quot;&lt;/span&gt;);

    &lt;span style="color:blue;"&gt;return &lt;/span&gt;value;
}&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;First we make sure the user didn’t access something outside the realm of the constraint parameter, e.g.:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:#2b91af;"&gt;Symbols&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt; &lt;strong&gt;&lt;u&gt;&lt;font color="#ff0000"&gt;oops&lt;/font&gt;&lt;/u&gt;&lt;/strong&gt; = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Symbols&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt;();
&lt;span style="color:blue;"&gt;var &lt;/span&gt;theo = &lt;span style="color:blue;"&gt;from &lt;/span&gt;t &lt;span style="color:blue;"&gt;in &lt;/span&gt;ctx.NewTheorem&amp;lt;&lt;span style="color:#2b91af;"&gt;Symbols&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt;&amp;gt;()
           &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.X1 - &lt;strong&gt;&lt;u&gt;&lt;font color="#ff0000"&gt;oops.&lt;/font&gt;&lt;/u&gt;&lt;/strong&gt;X2 &amp;gt;= 1
           &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.X1 - t.X2 &amp;lt;= 3
           &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.X1 == (2 * t.X3) + t.X5
           &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.X3 == t.X5
           &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.X2 == 6 * t.X4
           &lt;span style="color:blue;"&gt;select &lt;/span&gt;t;&lt;/pre&gt;
  &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;In essence this is some kind of scope check with regards to the expressed theorem. Recall the above corresponds to calls to the Where method that look as follows:&lt;/p&gt;

&lt;blockquote&gt;&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font face="Courier New"&gt;ctx.NewTheorem&amp;lt;&lt;span style="color:#2b91af;"&gt;Symbols&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt;&amp;gt;() .Where(t =&amp;gt; t.X1 - &lt;strong&gt;&lt;u&gt;&lt;font color="#ff0000"&gt;oops.&lt;/font&gt;&lt;/u&gt;&lt;/strong&gt;X2 &amp;gt;= 1)…&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We’ve captured the lambda expression parameter “t” in the AssertConstraints method and carry it on throughout the visitor so we can check it’s used as the left-hand side inside constraint expressions.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Note:&lt;/u&gt;&lt;/strong&gt; This restriction limits expressiveness quite a bit. For example, capturing an outer variable gives rise to a &lt;em&gt;closure&lt;/em&gt; to be created, which is accessed through field accesses (of type MemberExpression). Such potentially valid uses get rejected by the code above. To restore such functionality, one can employ partial compilation using LambdaExpression.Compile, after checking the expression doesn’t contain the lambda parameter. The essence is shown below:

    &lt;br /&gt;

    &lt;br /&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;if &lt;/font&gt;(member.Expression != param)

      &lt;br /&gt;{

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#0000ff"&gt;if &lt;/font&gt;(!IsLambdaParameterFree(member.Expression, param))

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#0000ff"&gt;throw new &lt;/font&gt;&lt;font color="#008080"&gt;NotSupportedException&lt;/font&gt;(&lt;font color="#800000"&gt;“Unsupported member expression using constraint parameter.”&lt;/font&gt;);

      &lt;br /&gt;

      &lt;br /&gt;&lt;font color="#008000"&gt;&amp;#160;&amp;#160;&amp;#160; // Evaluation outside Z3.&lt;/font&gt;

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#0000ff"&gt;object &lt;/font&gt;value = &lt;font color="#008080"&gt;Expression&lt;/font&gt;.Lambda(member.Expression).Compile().DynamicInvoke();

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#0000ff"&gt;return &lt;/font&gt;VisitConstant(context, &lt;font color="#008080"&gt;Expression&lt;/font&gt;.Constant(value));

      &lt;br /&gt;}

      &lt;br /&gt;&lt;/font&gt;

    &lt;br /&gt;We leave the implementation of such techniques to the reader, together with the task to hook this logic up in al the appropriate places (default case of Visit, in VisitCall further on, etc).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;VisitMember finally consults the environment to map the property access back to the Z3 object generated in the GetEnvironment call.&lt;/p&gt;

&lt;p&gt;Finally, we have a VisitCall method as well. Once more, I’ve kept some advanced rewriter stuff in here (to be explained in a subsequent post), so ignore that for the time being. The reason we implement VisitCall is to provide a means to expose advanced Z3 constructs efficiently, e.g. the Distinct operator. To do so, a Z3Methods class is provided:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color:green;"&gt;Z3 predicate methods.
&lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
&lt;/span&gt;&lt;span style="color:blue;"&gt;public static class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Z3Methods
&lt;/span&gt;{
    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Creates a predicate constraining the given symbols as distinct values.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Type of the parameters.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;param name=&amp;quot;symbols&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Symbols that are required to be distinct.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Predicate return value.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
    /// &amp;lt;remarks&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;This method should only be used within LINQ expressions.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/remarks&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public static bool &lt;/span&gt;Distinct&amp;lt;T&amp;gt;(&lt;span style="color:blue;"&gt;params &lt;/span&gt;T[] symbols &lt;span style="color:green;"&gt;/* type? */&lt;/span&gt;)
    {
        &lt;span style="color:blue;"&gt;throw new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;NotSupportedException&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;This method should only be used in query expressions.&amp;quot;&lt;/span&gt;);
    }
}&lt;/pre&gt;
  &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;This is very similar to the SqlMethods class of LINQ to SQL, and available for future extensions. VisitCall has the simple task to recognize calls to Z3Methods methods, turning them into the corresponding Z3 primitives.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color:green;"&gt;Visitor method to translate a method call expression.
&lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&amp;quot;context&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Z3 context.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;environment&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Environment with bindings of theorem variables to Z3 handles.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;call&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Method call expression.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;param&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Parameter used to express the constraint on.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Z3 expression handle.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;VisitCall(&lt;span style="color:#2b91af;"&gt;Context &lt;/span&gt;context, &lt;span style="color:#2b91af;"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;PropertyInfo&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;IntPtr&lt;/span&gt;&amp;gt; environment, &lt;span style="color:#2b91af;"&gt;MethodCallExpression &lt;/span&gt;call, &lt;span style="color:#2b91af;"&gt;ParameterExpression &lt;/span&gt;param)
{
    &lt;span style="color:blue;"&gt;var &lt;/span&gt;method = call.Method;

    &lt;span style="color:green;"&gt;//
    // Does the method have a rewriter attribute applied?
    //
    &lt;/span&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;rewriterAttr = (&lt;span style="color:#2b91af;"&gt;TheoremPredicateRewriterAttribute&lt;/span&gt;)method.GetCustomAttributes(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;TheoremPredicateRewriterAttribute&lt;/span&gt;), &lt;span style="color:blue;"&gt;false&lt;/span&gt;).SingleOrDefault();
    &lt;span style="color:blue;"&gt;if &lt;/span&gt;(rewriterAttr != &lt;span style="color:blue;"&gt;null&lt;/span&gt;)
    {
        &lt;span style="color:green;"&gt;//
        // Make sure the specified rewriter type implements the ITheoremPredicateRewriter.
        //
        &lt;/span&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;rewriterType = rewriterAttr.RewriterType;
        &lt;span style="color:blue;"&gt;if &lt;/span&gt;(!&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;ITheoremPredicateRewriter&lt;/span&gt;).IsAssignableFrom(rewriterType))
            &lt;span style="color:blue;"&gt;throw new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;InvalidOperationException&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Invalid predicate rewriter type definition. Did you implement ITheoremPredicateRewriter?&amp;quot;&lt;/span&gt;);

        &lt;span style="color:green;"&gt;//
        // Assume a parameterless public constructor to new up the rewriter.
        //
        &lt;/span&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;rewriter = (&lt;span style="color:#2b91af;"&gt;ITheoremPredicateRewriter&lt;/span&gt;)&lt;span style="color:#2b91af;"&gt;Activator&lt;/span&gt;.CreateInstance(rewriterType);

        &lt;span style="color:green;"&gt;//
        // Make sure we don&amp;#39;t get stuck when the rewriter just returned its input. Valid
        // rewriters should satisfy progress guarantees.
        //
        &lt;/span&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;result = rewriter.Rewrite(call);
        &lt;span style="color:blue;"&gt;if &lt;/span&gt;(result == call)
            &lt;span style="color:blue;"&gt;throw new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;InvalidOperationException&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;The expression tree rewriter of type &amp;quot; &lt;/span&gt;+ rewriterType.Name + &lt;span style="color:#a31515;"&gt;&amp;quot; did not perform any rewrite. Aborting compilation to avoid infinite looping.&amp;quot;&lt;/span&gt;);

        &lt;span style="color:green;"&gt;//
        // Visit the rewritten expression.
        //
        &lt;/span&gt;&lt;span style="color:blue;"&gt;return &lt;/span&gt;Visit(context, environment, result, param);
    }

    &lt;span style="color:green;"&gt;//
    // Filter for known Z3 operators.
    //
    &lt;/span&gt;&lt;span style="color:blue;"&gt;if &lt;/span&gt;(method.IsGenericMethod &amp;amp;&amp;amp; method.GetGenericMethodDefinition() == &lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;Z3Methods&lt;/span&gt;).GetMethod(&lt;span style="color:#a31515;"&gt;&amp;quot;Distinct&amp;quot;&lt;/span&gt;))
    {
        &lt;span style="color:green;"&gt;//
        // We know the signature of the Distinct method call. Its argument is a params
        // array, hence we expect a NewArrayExpression.
        //
        &lt;/span&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;arr = (&lt;span style="color:#2b91af;"&gt;NewArrayExpression&lt;/span&gt;)call.Arguments[0];
        &lt;span style="color:blue;"&gt;var &lt;/span&gt;args = &lt;span style="color:blue;"&gt;from &lt;/span&gt;arg &lt;span style="color:blue;"&gt;in &lt;/span&gt;arr.Expressions &lt;span style="color:blue;"&gt;select &lt;/span&gt;Visit(context, environment, arg, param);
        &lt;span style="color:blue;"&gt;return &lt;/span&gt;context.MkDistinct(args.ToArray());
    }
    &lt;span style="color:blue;"&gt;else
        throw new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;NotSupportedException&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Unknown method call:&amp;quot; &lt;/span&gt;+ method.ToString());
}&lt;/pre&gt;
  &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;In particular, a call to Distinct is processed by inspecting its argument corresponding to the params-array, recursively translating any of its elements (e.g. Z3Methods.Distinct(1, 2, s.X1, s.X2) will give rise to two constant expressions and two member accesses, but more complex expressions can occur as the arguments as well…). Ultimately, MkDistinct is called and all is happy.&lt;/p&gt;

&lt;p&gt;Now that we’re done investigating the visitor, we can have a look at the final stage of the LINQ to Z3-driven theorem solving, the &lt;em&gt;get solution&lt;/em&gt; phase.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h1&gt;Getting the solution&lt;/h1&gt;

&lt;p&gt;To expose the solution to the user, we new up a Plain Old CLR Object (POCO) of the theorem’s generic parameter type T. All there’s left to do here is to use some reflection voodoo to instantiate T, populate its properties somehow, and return the object. Different situations can occur, based on the way the type is defined. In particular, use of an anonymous type gives some problems as there’s no formal correlation between the generated constructor and the type’s properties (which are get-only, so we can’t assign values directly). This isn’t super-exciting stuff, but nonetheless:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color:green;"&gt;Gets the solution object for the solved theorem.
&lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;typeparam name=&amp;quot;T&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Environment type to create an instance of.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
/// &amp;lt;param name=&amp;quot;model&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Z3 model to evaluate theorem parameters under.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;environment&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Environment with bindings of theorem variables to Z3 handles.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Instance of the enviroment type with theorem-satisfying values.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color:blue;"&gt;private static &lt;/span&gt;T GetSolution&amp;lt;T&amp;gt;(&lt;span style="color:#2b91af;"&gt;Model &lt;/span&gt;model, &lt;span style="color:#2b91af;"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;PropertyInfo&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;IntPtr&lt;/span&gt;&amp;gt; environment)
{
    &lt;span style="color:#2b91af;"&gt;Type &lt;/span&gt;t = &lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(T);

    &lt;span style="color:green;"&gt;//
    // Determine whether T is a compiler-generated type, indicating an anonymous type.
    // This check might not be reliable enough but works for now.
    //
    &lt;/span&gt;&lt;span style="color:blue;"&gt;if &lt;/span&gt;(t.GetCustomAttributes(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;CompilerGeneratedAttribute&lt;/span&gt;), &lt;span style="color:blue;"&gt;false&lt;/span&gt;).Any())
    {
        &lt;span style="color:green;"&gt;//
        // Anonymous types have a constructor that takes in values for all its properties.
        // However, we don&amp;#39;t know the order and it&amp;#39;s hard to correlate back the parameters
        // to the underlying properties. So, we want to bypass that constructor altogether
        // by using the FormatterServices to create an uninitialized (all-zero) instance.
        //
        &lt;/span&gt;T result = (T)&lt;span style="color:#2b91af;"&gt;FormatterServices&lt;/span&gt;.GetUninitializedObject(t);

        &lt;span style="color:green;"&gt;//
        // Here we take advantage of undesirable knowledge on how anonymous types are
        // implemented by the C# compiler. This is risky but we can live with it for
        // now in this POC. Because the properties are get-only, we need to perform
        // nominal matching with the corresponding backing fields.
        //
        &lt;/span&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;fields = t.GetFields(&lt;span style="color:#2b91af;"&gt;BindingFlags&lt;/span&gt;.NonPublic | &lt;span style="color:#2b91af;"&gt;BindingFlags&lt;/span&gt;.Instance);
        &lt;span style="color:blue;"&gt;foreach &lt;/span&gt;(&lt;span style="color:blue;"&gt;var &lt;/span&gt;parameter &lt;span style="color:blue;"&gt;in &lt;/span&gt;environment.Keys)
        {
            &lt;span style="color:green;"&gt;//
            // Mapping from property to field.
            //
            &lt;/span&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;field = fields.Where(f =&amp;gt; f.Name.StartsWith(&lt;span style="color:#a31515;"&gt;&amp;quot;&amp;lt;&amp;quot; &lt;/span&gt;+ parameter.Name + &lt;span style="color:#a31515;"&gt;&amp;quot;&amp;gt;&amp;quot;&lt;/span&gt;)).SingleOrDefault();

            &lt;span style="color:green;"&gt;//
            // Evaluation of the values though the handle in the environment bindings.
            //
            &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;val = model.Eval(environment[parameter]);
            &lt;span style="color:blue;"&gt;if &lt;/span&gt;(parameter.PropertyType == &lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:blue;"&gt;bool&lt;/span&gt;))
                field.SetValue(result, model.GetBoolValueBool(val));
            &lt;span style="color:blue;"&gt;else if &lt;/span&gt;(parameter.PropertyType == &lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:blue;"&gt;int&lt;/span&gt;))
                field.SetValue(result, model.GetNumeralValueInt(val));
            &lt;span style="color:blue;"&gt;else
                throw new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;NotSupportedException&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Unsupported parameter type for &amp;quot; &lt;/span&gt;+ parameter.Name + &lt;span style="color:#a31515;"&gt;&amp;quot;.&amp;quot;&lt;/span&gt;);
        }

        &lt;span style="color:blue;"&gt;return &lt;/span&gt;result;
    }
    &lt;span style="color:blue;"&gt;else
    &lt;/span&gt;{
        &lt;span style="color:green;"&gt;//
        // Straightforward case of having an &amp;quot;onymous type&amp;quot; at hand.
        //
        &lt;/span&gt;T result = &lt;span style="color:#2b91af;"&gt;Activator&lt;/span&gt;.CreateInstance&amp;lt;T&amp;gt;();

        &lt;span style="color:blue;"&gt;foreach &lt;/span&gt;(&lt;span style="color:blue;"&gt;var &lt;/span&gt;parameter &lt;span style="color:blue;"&gt;in &lt;/span&gt;environment.Keys)
        {
            &lt;span style="color:green;"&gt;//
            // Normalize types when facing Z3. Theorem variable type mappings allow for strong
            // typing within the theorem, while underlying variable representations are Z3-
            // friendly types.
            //
            &lt;/span&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;parameterType = parameter.PropertyType;
            &lt;span style="color:blue;"&gt;var &lt;/span&gt;parameterTypeMapping = (&lt;span style="color:#2b91af;"&gt;TheoremVariableTypeMappingAttribute&lt;/span&gt;)parameterType.GetCustomAttributes(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;TheoremVariableTypeMappingAttribute&lt;/span&gt;), &lt;span style="color:blue;"&gt;false&lt;/span&gt;).SingleOrDefault();
            &lt;span style="color:blue;"&gt;if &lt;/span&gt;(parameterTypeMapping != &lt;span style="color:blue;"&gt;null&lt;/span&gt;)
                parameterType = parameterTypeMapping.RegularType;

            &lt;span style="color:green;"&gt;//
            // Evaluation of the values though the handle in the environment bindings.
            //
            &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;val = model.Eval(environment[parameter]);
            &lt;span style="color:blue;"&gt;object &lt;/span&gt;value;
            &lt;span style="color:blue;"&gt;if &lt;/span&gt;(parameterType == &lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:blue;"&gt;bool&lt;/span&gt;))
                value = model.GetBoolValueBool(val);
            &lt;span style="color:blue;"&gt;else if &lt;/span&gt;(parameterType == &lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:blue;"&gt;int&lt;/span&gt;))
                value = model.GetNumeralValueInt(val);
            &lt;span style="color:blue;"&gt;else
                throw new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;NotSupportedException&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Unsupported parameter type for &amp;quot; &lt;/span&gt;+ parameter.Name + &lt;span style="color:#a31515;"&gt;&amp;quot;.&amp;quot;&lt;/span&gt;);

            &lt;span style="color:green;"&gt;//
            // If there was a type mapping, we need to convert back to the original type.
            // In that case we expect a constructor with the mapped type to be available.
            //
            &lt;/span&gt;&lt;span style="color:blue;"&gt;if &lt;/span&gt;(parameterTypeMapping != &lt;span style="color:blue;"&gt;null&lt;/span&gt;)
            {
                &lt;span style="color:blue;"&gt;var &lt;/span&gt;ctor = parameter.PropertyType.GetConstructor(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Type&lt;/span&gt;[] { parameterType });
                &lt;span style="color:blue;"&gt;if &lt;/span&gt;(ctor == &lt;span style="color:blue;"&gt;null&lt;/span&gt;)
                    &lt;span style="color:blue;"&gt;throw new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;InvalidOperationException&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Could not construct an instance of the mapped type &amp;quot; &lt;/span&gt;+ parameter.PropertyType.Name + &lt;span style="color:#a31515;"&gt;&amp;quot;. No public constructor with parameter type &amp;quot; &lt;/span&gt;+ parameterType + &lt;span style="color:#a31515;"&gt;&amp;quot; found.&amp;quot;&lt;/span&gt;);

                value = ctor.Invoke(&lt;span style="color:blue;"&gt;new object&lt;/span&gt;[] { value });
            }

            parameter.SetValue(result, value, &lt;span style="color:blue;"&gt;null&lt;/span&gt;);
        }

        &lt;span style="color:blue;"&gt;return &lt;/span&gt;result;
    }
}&lt;/pre&gt;
  &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;Focus on the non-anonymous type case at the bottom, ignoring parts on type mappings (part of the stuff to be explained another time). The essence is plain simple:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Create an instance of the type.&lt;/li&gt;

  &lt;li&gt;Go over the environment and:&lt;/li&gt;

  &lt;ul&gt;
    &lt;li&gt;Extract the value from the Z3 model using the environment’s stored Z3 object.&lt;/li&gt;

    &lt;li&gt;Assign it to the property.&lt;/li&gt;
  &lt;/ul&gt;
&lt;/ul&gt;

&lt;p&gt;Notice get-only properties are not supported, though one could look at LINQ to SQL as a source of inspiration to deal with such cases as well, if desired.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h1&gt;Samples&lt;/h1&gt;

&lt;p&gt;A few samples of simple theorems using the infrastructure provided above are shown below:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&amp;#160;&lt;/p&gt;

  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;using &lt;/span&gt;(&lt;span style="color:blue;"&gt;var &lt;/span&gt;ctx = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Z3Context&lt;/span&gt;())
{
    ctx.Log = &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.Out;

    Print(&lt;span style="color:blue;"&gt;from &lt;/span&gt;t &lt;span style="color:blue;"&gt;in &lt;/span&gt;ctx.NewTheorem(&lt;span style="color:blue;"&gt;new &lt;/span&gt;{ x = &lt;span style="color:blue;"&gt;default&lt;/span&gt;(&lt;span style="color:blue;"&gt;bool&lt;/span&gt;) })
          &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.x &amp;amp;&amp;amp; !t.x
          &lt;span style="color:blue;"&gt;select &lt;/span&gt;t);

    Print(&lt;span style="color:blue;"&gt;from &lt;/span&gt;t &lt;span style="color:blue;"&gt;in &lt;/span&gt;ctx.NewTheorem(&lt;span style="color:blue;"&gt;new &lt;/span&gt;{ x = &lt;span style="color:blue;"&gt;default&lt;/span&gt;(&lt;span style="color:blue;"&gt;bool&lt;/span&gt;), y = &lt;span style="color:blue;"&gt;default&lt;/span&gt;(&lt;span style="color:blue;"&gt;bool&lt;/span&gt;) })
          &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.x ^ t.y
          &lt;span style="color:blue;"&gt;select &lt;/span&gt;t);

    Print(&lt;span style="color:blue;"&gt;from &lt;/span&gt;t &lt;span style="color:blue;"&gt;in &lt;/span&gt;ctx.NewTheorem(&lt;span style="color:blue;"&gt;new &lt;/span&gt;{ x = &lt;span style="color:blue;"&gt;default&lt;/span&gt;(&lt;span style="color:blue;"&gt;int&lt;/span&gt;), y = &lt;span style="color:blue;"&gt;default&lt;/span&gt;(&lt;span style="color:blue;"&gt;int&lt;/span&gt;) })
          &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.x &amp;lt; t.y + 1
          &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.x &amp;gt; 2
          &lt;span style="color:blue;"&gt;select &lt;/span&gt;t);

    Print(&lt;span style="color:blue;"&gt;from &lt;/span&gt;t &lt;span style="color:blue;"&gt;in &lt;/span&gt;ctx.NewTheorem&amp;lt;&lt;span style="color:#2b91af;"&gt;Symbols&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt;&amp;gt;()
          &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.X1 &amp;lt; t.X2 + 1
          &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.X1 &amp;gt; 2
          &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.X1 != t.X2
          &lt;span style="color:blue;"&gt;select &lt;/span&gt;t);

    Print(&lt;span style="color:blue;"&gt;from &lt;/span&gt;t &lt;span style="color:blue;"&gt;in &lt;/span&gt;ctx.NewTheorem&amp;lt;&lt;span style="color:#2b91af;"&gt;Symbols&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt;&amp;gt;()
          &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.X1 - t.X2 &amp;gt;= 1
          &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.X1 - t.X2 &amp;lt;= 3
          &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.X1 == (2 * t.X3) + t.X5
          &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.X3 == t.X5
          &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.X2 == 6 * t.X4
          &lt;span style="color:blue;"&gt;select &lt;/span&gt;t);

    Print(&lt;span style="color:blue;"&gt;from &lt;/span&gt;t &lt;span style="color:blue;"&gt;in &lt;/span&gt;ctx.NewTheorem&amp;lt;&lt;span style="color:#2b91af;"&gt;Symbols&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt;&amp;gt;()
          &lt;span style="color:blue;"&gt;where &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Z3Methods&lt;/span&gt;.Distinct(t.X1, t.X2)
          &lt;span style="color:blue;"&gt;select &lt;/span&gt;t);&lt;br /&gt;}&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;The reader should be able to trace through those samples mentally without much trouble. The Print method is shown below:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;private static void &lt;/span&gt;Print&amp;lt;T&amp;gt;(&lt;span style="color:#2b91af;"&gt;Theorem&lt;/span&gt;&amp;lt;T&amp;gt; t) &lt;span style="color:blue;"&gt;where &lt;/span&gt;T : &lt;span style="color:blue;"&gt;class
&lt;/span&gt;{
    &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(t);
    &lt;span style="color:blue;"&gt;var &lt;/span&gt;res = t.Solve();
    &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(res == &lt;span style="color:blue;"&gt;null &lt;/span&gt;? &lt;span style="color:#a31515;"&gt;&amp;quot;none&amp;quot; &lt;/span&gt;: res.ToString());
    &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine();
}&lt;/pre&gt;
  &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;Given all of this, the output looks as follows:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;a href="http://bartdesmet.net/images_wlw/LINQtoZ3TheoremSolvingonSteroidsPart1_12E1C/image.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://bartdesmet.net/images_wlw/LINQtoZ3TheoremSolvingonSteroidsPart1_12E1C/image_thumb.png" width="677" height="426" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sweet! Notice the use of the Log property on the context object causes the constraints to be emitted to the screen, in LISP-style prefix notation for operators and operands.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h1&gt;Sneak peak&lt;/h1&gt;

&lt;p&gt;Given the baseline infrastructure we covered in this post, we can start adding layers of abstraction over it to make more advanced theorems easier to express. An example is a Sudoku puzzle:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;s1 = &lt;span style="color:blue;"&gt;from &lt;/span&gt;t &lt;span style="color:blue;"&gt;in &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Sudoku&lt;/span&gt;.Create(ctx)
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.Cell13 == 2 &amp;amp;&amp;amp; t.Cell16 == 1 &amp;amp;&amp;amp; t.Cell18 == 6
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.Cell23 == 7 &amp;amp;&amp;amp; t.Cell26 == 4 
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.Cell31 == 5 &amp;amp;&amp;amp; t.Cell37 == 9
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.Cell42 == 1 &amp;amp;&amp;amp; t.Cell44 == 3
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.Cell51 == 8 &amp;amp;&amp;amp; t.Cell55 == 5 &amp;amp;&amp;amp; t.Cell59 == 4
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.Cell66 == 6 &amp;amp;&amp;amp; t.Cell68 == 2
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.Cell73 == 6 &amp;amp;&amp;amp; t.Cell79 == 7
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.Cell84 == 8 &amp;amp;&amp;amp; t.Cell87 == 3
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.Cell92 == 4 &amp;amp;&amp;amp; t.Cell94 == 9 &amp;amp;&amp;amp; t.Cell97 == 2
         &lt;span style="color:blue;"&gt;select &lt;/span&gt;t;

&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(s1);
&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(s1.Solve());
&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine();&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;Or more compactly represented as a string:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;s2 = &lt;span style="color:#2b91af;"&gt;Sudoku&lt;/span&gt;.Parse(ctx, &lt;span style="color:#a31515;"&gt;@&amp;quot;..2..1.6.
                             ..7..4...
                             5.....9..
                             .1.3.....
                             8...5...4
                             .....6.2.
                             ..6.....7
                             ...8..3..
                             .4.9..2..&amp;quot;&lt;/span&gt;);
&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(s2);
&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(s2.Solve());
&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine();&lt;/pre&gt;
  &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;Here we’ve created a domain-specific theorem type, Sudoku, that’s responsible to provide parts of the constraints. In fact, a Sudoku has much more constraints than the ones specified by the user: rows, columns and blocks need to contain unique values from 1-9, and every cell has to be within that range. For the innocent-looking Sudoku above, we get the following set of constraints:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font face="Courier New"&gt;((1 &amp;lt;= p.Cell11) &amp;amp;&amp;amp; (p.Cell11 &amp;lt;= 9)),
      &lt;br /&gt;((1 &amp;lt;= p.Cell12) &amp;amp;&amp;amp; (p.Cell12 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell13) &amp;amp;&amp;amp; (p.Cell13 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell14) &amp;amp;&amp;amp; (p.Cell14 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell15) &amp;amp;&amp;amp; (p.Cell15 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell16) &amp;amp;&amp;amp; (p.Cell16 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell17) &amp;amp;&amp;amp; (p.Cell17 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell18) &amp;amp;&amp;amp; (p.Cell18 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell19) &amp;amp;&amp;amp; (p.Cell19 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell21) &amp;amp;&amp;amp; (p.Cell21 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell22) &amp;amp;&amp;amp; (p.Cell22 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell23) &amp;amp;&amp;amp; (p.Cell23 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell24) &amp;amp;&amp;amp; (p.Cell24 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell25) &amp;amp;&amp;amp; (p.Cell25 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell26) &amp;amp;&amp;amp; (p.Cell26 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell27) &amp;amp;&amp;amp; (p.Cell27 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell28) &amp;amp;&amp;amp; (p.Cell28 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell29) &amp;amp;&amp;amp; (p.Cell29 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell31) &amp;amp;&amp;amp; (p.Cell31 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell32) &amp;amp;&amp;amp; (p.Cell32 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell33) &amp;amp;&amp;amp; (p.Cell33 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell34) &amp;amp;&amp;amp; (p.Cell34 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell35) &amp;amp;&amp;amp; (p.Cell35 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell36) &amp;amp;&amp;amp; (p.Cell36 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell37) &amp;amp;&amp;amp; (p.Cell37 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell38) &amp;amp;&amp;amp; (p.Cell38 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell39) &amp;amp;&amp;amp; (p.Cell39 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell41) &amp;amp;&amp;amp; (p.Cell41 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell42) &amp;amp;&amp;amp; (p.Cell42 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell43) &amp;amp;&amp;amp; (p.Cell43 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell44) &amp;amp;&amp;amp; (p.Cell44 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell45) &amp;amp;&amp;amp; (p.Cell45 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell46) &amp;amp;&amp;amp; (p.Cell46 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell47) &amp;amp;&amp;amp; (p.Cell47 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell48) &amp;amp;&amp;amp; (p.Cell48 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell49) &amp;amp;&amp;amp; (p.Cell49 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell51) &amp;amp;&amp;amp; (p.Cell51 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell52) &amp;amp;&amp;amp; (p.Cell52 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell53) &amp;amp;&amp;amp; (p.Cell53 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell54) &amp;amp;&amp;amp; (p.Cell54 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell55) &amp;amp;&amp;amp; (p.Cell55 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell56) &amp;amp;&amp;amp; (p.Cell56 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell57) &amp;amp;&amp;amp; (p.Cell57 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell58) &amp;amp;&amp;amp; (p.Cell58 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell59) &amp;amp;&amp;amp; (p.Cell59 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell61) &amp;amp;&amp;amp; (p.Cell61 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell62) &amp;amp;&amp;amp; (p.Cell62 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell63) &amp;amp;&amp;amp; (p.Cell63 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell64) &amp;amp;&amp;amp; (p.Cell64 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell65) &amp;amp;&amp;amp; (p.Cell65 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell66) &amp;amp;&amp;amp; (p.Cell66 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell67) &amp;amp;&amp;amp; (p.Cell67 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell68) &amp;amp;&amp;amp; (p.Cell68 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell69) &amp;amp;&amp;amp; (p.Cell69 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell71) &amp;amp;&amp;amp; (p.Cell71 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell72) &amp;amp;&amp;amp; (p.Cell72 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell73) &amp;amp;&amp;amp; (p.Cell73 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell74) &amp;amp;&amp;amp; (p.Cell74 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell75) &amp;amp;&amp;amp; (p.Cell75 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell76) &amp;amp;&amp;amp; (p.Cell76 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell77) &amp;amp;&amp;amp; (p.Cell77 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell78) &amp;amp;&amp;amp; (p.Cell78 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell79) &amp;amp;&amp;amp; (p.Cell79 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell81) &amp;amp;&amp;amp; (p.Cell81 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell82) &amp;amp;&amp;amp; (p.Cell82 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell83) &amp;amp;&amp;amp; (p.Cell83 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell84) &amp;amp;&amp;amp; (p.Cell84 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell85) &amp;amp;&amp;amp; (p.Cell85 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell86) &amp;amp;&amp;amp; (p.Cell86 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell87) &amp;amp;&amp;amp; (p.Cell87 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell88) &amp;amp;&amp;amp; (p.Cell88 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell89) &amp;amp;&amp;amp; (p.Cell89 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell91) &amp;amp;&amp;amp; (p.Cell91 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell92) &amp;amp;&amp;amp; (p.Cell92 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell93) &amp;amp;&amp;amp; (p.Cell93 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell94) &amp;amp;&amp;amp; (p.Cell94 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell95) &amp;amp;&amp;amp; (p.Cell95 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell96) &amp;amp;&amp;amp; (p.Cell96 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell97) &amp;amp;&amp;amp; (p.Cell97 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell98) &amp;amp;&amp;amp; (p.Cell98 &amp;lt;= 9)),

      &lt;br /&gt;((1 &amp;lt;= p.Cell99) &amp;amp;&amp;amp; (p.Cell99 &amp;lt;= 9)),

      &lt;br /&gt;Distinct(new [] {p.Cell11, p.Cell12, p.Cell13, p.Cell14, p.Cell15, p.Cell16, p.Cell17, p.Cell18, p.Cell19}),

      &lt;br /&gt;Distinct(new [] {p.Cell21, p.Cell22, p.Cell23, p.Cell24, p.Cell25, p.Cell26, p.Cell27, p.Cell28, p.Cell29}),

      &lt;br /&gt;Distinct(new [] {p.Cell31, p.Cell32, p.Cell33, p.Cell34, p.Cell35, p.Cell36, p.Cell37, p.Cell38, p.Cell39}), 

      &lt;br /&gt;Distinct(new [] {p.Cell41, p.Cell42, p.Cell43, p.Cell44, p.Cell45, p.Cell46, p.Cell47, p.Cell48, p.Cell49}), 

      &lt;br /&gt;Distinct(new [] {p.Cell51, p.Cell52, p.Cell53, p.Cell54, p.Cell55, p.Cell56, p.Cell57, p.Cell58, p.Cell59}), 

      &lt;br /&gt;Distinct(new [] {p.Cell61, p.Cell62, p.Cell63, p.Cell64, p.Cell65, p.Cell66, p.Cell67, p.Cell68, p.Cell69}), 

      &lt;br /&gt;Distinct(new [] {p.Cell71, p.Cell72, p.Cell73, p.Cell74, p.Cell75, p.Cell76, p.Cell77, p.Cell78, p.Cell79}), 

      &lt;br /&gt;Distinct(new [] {p.Cell81, p.Cell82, p.Cell83, p.Cell84, p.Cell85, p.Cell86, p.Cell87, p.Cell88, p.Cell89}), 

      &lt;br /&gt;Distinct(new [] {p.Cell91, p.Cell92, p.Cell93, p.Cell94, p.Cell95, p.Cell96, p.Cell97, p.Cell98, p.Cell99}), 

      &lt;br /&gt;Distinct(new [] {p.Cell11, p.Cell21, p.Cell31, p.Cell41, p.Cell51, p.Cell61, p.Cell71, p.Cell81, p.Cell91}), 

      &lt;br /&gt;Distinct(new [] {p.Cell12, p.Cell22, p.Cell32, p.Cell42, p.Cell52, p.Cell62, p.Cell72, p.Cell82, p.Cell92}), 

      &lt;br /&gt;Distinct(new [] {p.Cell13, p.Cell23, p.Cell33, p.Cell43, p.Cell53, p.Cell63, p.Cell73, p.Cell83, p.Cell93}), 

      &lt;br /&gt;Distinct(new [] {p.Cell14, p.Cell24, p.Cell34, p.Cell44, p.Cell54, p.Cell64, p.Cell74, p.Cell84, p.Cell94}), 

      &lt;br /&gt;Distinct(new [] {p.Cell15, p.Cell25, p.Cell35, p.Cell45, p.Cell55, p.Cell65, p.Cell75, p.Cell85, p.Cell95}), 

      &lt;br /&gt;Distinct(new [] {p.Cell16, p.Cell26, p.Cell36, p.Cell46, p.Cell56, p.Cell66, p.Cell76, p.Cell86, p.Cell96}),

      &lt;br /&gt;Distinct(new [] {p.Cell17, p.Cell27, p.Cell37, p.Cell47, p.Cell57, p.Cell67, p.Cell77, p.Cell87, p.Cell97}),

      &lt;br /&gt;Distinct(new [] {p.Cell18, p.Cell28, p.Cell38, p.Cell48, p.Cell58, p.Cell68, p.Cell78, p.Cell88, p.Cell98}),

      &lt;br /&gt;Distinct(new [] {p.Cell19, p.Cell29, p.Cell39, p.Cell49, p.Cell59, p.Cell69, p.Cell79, p.Cell89, p.Cell99}),

      &lt;br /&gt;Distinct(new [] {p.Cell11, p.Cell12, p.Cell13, p.Cell21, p.Cell22, p.Cell23, p.Cell31, p.Cell32, p.Cell33}),

      &lt;br /&gt;Distinct(new [] {p.Cell14, p.Cell15, p.Cell16, p.Cell24, p.Cell25, p.Cell26, p.Cell34, p.Cell35, p.Cell36}), 

      &lt;br /&gt;Distinct(new [] {p.Cell17, p.Cell18, p.Cell19, p.Cell27, p.Cell28, p.Cell29, p.Cell37, p.Cell38, p.Cell39}), 

      &lt;br /&gt;Distinct(new [] {p.Cell41, p.Cell42, p.Cell43, p.Cell51, p.Cell52, p.Cell53, p.Cell61, p.Cell62, p.Cell63}),

      &lt;br /&gt;Distinct(new [] {p.Cell44, p.Cell45, p.Cell46, p.Cell54, p.Cell55, p.Cell56, p.Cell64, p.Cell65, p.Cell66}),

      &lt;br /&gt;Distinct(new [] {p.Cell47, p.Cell48, p.Cell49, p.Cell57, p.Cell58, p.Cell59, p.Cell67, p.Cell68, p.Cell69}), 

      &lt;br /&gt;Distinct(new [] {p.Cell71, p.Cell72, p.Cell73, p.Cell81, p.Cell82, p.Cell83, p.Cell91, p.Cell92, p.Cell93}),

      &lt;br /&gt;Distinct(new [] {p.Cell74, p.Cell75, p.Cell76, p.Cell84, p.Cell85, p.Cell86, p.Cell94, p.Cell95, p.Cell96}),

      &lt;br /&gt;Distinct(new [] {p.Cell77, p.Cell78, p.Cell79, p.Cell87, p.Cell88, p.Cell89, p.Cell97, p.Cell98, p.Cell99}),

      &lt;br /&gt;(and (&amp;lt;= 1 Cell11) (&amp;lt;= Cell11 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell12) (&amp;lt;= Cell12 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell13) (&amp;lt;= Cell13 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell14) (&amp;lt;= Cell14 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell15) (&amp;lt;= Cell15 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell16) (&amp;lt;= Cell16 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell17) (&amp;lt;= Cell17 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell18) (&amp;lt;= Cell18 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell19) (&amp;lt;= Cell19 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell21) (&amp;lt;= Cell21 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell22) (&amp;lt;= Cell22 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell23) (&amp;lt;= Cell23 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell24) (&amp;lt;= Cell24 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell25) (&amp;lt;= Cell25 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell26) (&amp;lt;= Cell26 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell27) (&amp;lt;= Cell27 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell28) (&amp;lt;= Cell28 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell29) (&amp;lt;= Cell29 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell31) (&amp;lt;= Cell31 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell32) (&amp;lt;= Cell32 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell33) (&amp;lt;= Cell33 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell34) (&amp;lt;= Cell34 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell35) (&amp;lt;= Cell35 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell36) (&amp;lt;= Cell36 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell37) (&amp;lt;= Cell37 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell38) (&amp;lt;= Cell38 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell39) (&amp;lt;= Cell39 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell41) (&amp;lt;= Cell41 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell42) (&amp;lt;= Cell42 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell43) (&amp;lt;= Cell43 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell44) (&amp;lt;= Cell44 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell45) (&amp;lt;= Cell45 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell46) (&amp;lt;= Cell46 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell47) (&amp;lt;= Cell47 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell48) (&amp;lt;= Cell48 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell49) (&amp;lt;= Cell49 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell51) (&amp;lt;= Cell51 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell52) (&amp;lt;= Cell52 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell53) (&amp;lt;= Cell53 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell54) (&amp;lt;= Cell54 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell55) (&amp;lt;= Cell55 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell56) (&amp;lt;= Cell56 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell57) (&amp;lt;= Cell57 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell58) (&amp;lt;= Cell58 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell59) (&amp;lt;= Cell59 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell61) (&amp;lt;= Cell61 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell62) (&amp;lt;= Cell62 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell63) (&amp;lt;= Cell63 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell64) (&amp;lt;= Cell64 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell65) (&amp;lt;= Cell65 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell66) (&amp;lt;= Cell66 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell67) (&amp;lt;= Cell67 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell68) (&amp;lt;= Cell68 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell69) (&amp;lt;= Cell69 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell71) (&amp;lt;= Cell71 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell72) (&amp;lt;= Cell72 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell73) (&amp;lt;= Cell73 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell74) (&amp;lt;= Cell74 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell75) (&amp;lt;= Cell75 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell76) (&amp;lt;= Cell76 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell77) (&amp;lt;= Cell77 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell78) (&amp;lt;= Cell78 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell79) (&amp;lt;= Cell79 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell81) (&amp;lt;= Cell81 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell82) (&amp;lt;= Cell82 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell83) (&amp;lt;= Cell83 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell84) (&amp;lt;= Cell84 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell85) (&amp;lt;= Cell85 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell86) (&amp;lt;= Cell86 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell87) (&amp;lt;= Cell87 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell88) (&amp;lt;= Cell88 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell89) (&amp;lt;= Cell89 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell91) (&amp;lt;= Cell91 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell92) (&amp;lt;= Cell92 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell93) (&amp;lt;= Cell93 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell94) (&amp;lt;= Cell94 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell95) (&amp;lt;= Cell95 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell96) (&amp;lt;= Cell96 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell97) (&amp;lt;= Cell97 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell98) (&amp;lt;= Cell98 9))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell99) (&amp;lt;= Cell99 9))

      &lt;br /&gt;(distinct Cell11 Cell12 Cell13 Cell14 Cell15 Cell16 Cell17 Cell18 Cell19)

      &lt;br /&gt;(distinct Cell21 Cell22 Cell23 Cell24 Cell25 Cell26 Cell27 Cell28 Cell29)

      &lt;br /&gt;(distinct Cell31 Cell32 Cell33 Cell34 Cell35 Cell36 Cell37 Cell38 Cell39)

      &lt;br /&gt;(distinct Cell41 Cell42 Cell43 Cell44 Cell45 Cell46 Cell47 Cell48 Cell49)

      &lt;br /&gt;(distinct Cell51 Cell52 Cell53 Cell54 Cell55 Cell56 Cell57 Cell58 Cell59)

      &lt;br /&gt;(distinct Cell61 Cell62 Cell63 Cell64 Cell65 Cell66 Cell67 Cell68 Cell69)

      &lt;br /&gt;(distinct Cell71 Cell72 Cell73 Cell74 Cell75 Cell76 Cell77 Cell78 Cell79)

      &lt;br /&gt;(distinct Cell81 Cell82 Cell83 Cell84 Cell85 Cell86 Cell87 Cell88 Cell89)

      &lt;br /&gt;(distinct Cell91 Cell92 Cell93 Cell94 Cell95 Cell96 Cell97 Cell98 Cell99)

      &lt;br /&gt;(distinct Cell11 Cell21 Cell31 Cell41 Cell51 Cell61 Cell71 Cell81 Cell91)

      &lt;br /&gt;(distinct Cell12 Cell22 Cell32 Cell42 Cell52 Cell62 Cell72 Cell82 Cell92)

      &lt;br /&gt;(distinct Cell13 Cell23 Cell33 Cell43 Cell53 Cell63 Cell73 Cell83 Cell93)

      &lt;br /&gt;(distinct Cell14 Cell24 Cell34 Cell44 Cell54 Cell64 Cell74 Cell84 Cell94)

      &lt;br /&gt;(distinct Cell15 Cell25 Cell35 Cell45 Cell55 Cell65 Cell75 Cell85 Cell95)

      &lt;br /&gt;(distinct Cell16 Cell26 Cell36 Cell46 Cell56 Cell66 Cell76 Cell86 Cell96)

      &lt;br /&gt;(distinct Cell17 Cell27 Cell37 Cell47 Cell57 Cell67 Cell77 Cell87 Cell97)

      &lt;br /&gt;(distinct Cell18 Cell28 Cell38 Cell48 Cell58 Cell68 Cell78 Cell88 Cell98)

      &lt;br /&gt;(distinct Cell19 Cell29 Cell39 Cell49 Cell59 Cell69 Cell79 Cell89 Cell99)

      &lt;br /&gt;(distinct Cell11 Cell12 Cell13 Cell21 Cell22 Cell23 Cell31 Cell32 Cell33)

      &lt;br /&gt;(distinct Cell14 Cell15 Cell16 Cell24 Cell25 Cell26 Cell34 Cell35 Cell36)

      &lt;br /&gt;(distinct Cell17 Cell18 Cell19 Cell27 Cell28 Cell29 Cell37 Cell38 Cell39)

      &lt;br /&gt;(distinct Cell41 Cell42 Cell43 Cell51 Cell52 Cell53 Cell61 Cell62 Cell63)

      &lt;br /&gt;(distinct Cell44 Cell45 Cell46 Cell54 Cell55 Cell56 Cell64 Cell65 Cell66)

      &lt;br /&gt;(distinct Cell47 Cell48 Cell49 Cell57 Cell58 Cell59 Cell67 Cell68 Cell69)

      &lt;br /&gt;(distinct Cell71 Cell72 Cell73 Cell81 Cell82 Cell83 Cell91 Cell92 Cell93)

      &lt;br /&gt;(distinct Cell74 Cell75 Cell76 Cell84 Cell85 Cell86 Cell94 Cell95 Cell96)

      &lt;br /&gt;(distinct Cell77 Cell78 Cell79 Cell87 Cell88 Cell89 Cell97 Cell98 Cell99)

      &lt;br /&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;(and (and (= Cell13 2) (= Cell16 1)) (= Cell18 6))
          &lt;br /&gt;(and (= Cell23 7) (= Cell26 4))

          &lt;br /&gt;(and (= Cell31 5) (= Cell37 9))

          &lt;br /&gt;(and (= Cell42 1) (= Cell44 3))

          &lt;br /&gt;(and (and (= Cell51 8) (= Cell55 5)) (= Cell59 4))

          &lt;br /&gt;(and (= Cell66 6) (= Cell68 2))

          &lt;br /&gt;(and (= Cell73 6) (= Cell79 7))

          &lt;br /&gt;(and (= Cell84 8) (= Cell87 3))

          &lt;br /&gt;(and (and (= Cell92 4) (= Cell94 9)) (= Cell97 2))&lt;/font&gt;&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;

  &lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Only the last nine lines were specified by the user through the LINQ query expression. In fact, the reader should be able to create a Sudoku class already based on today’s literature (tip: work your way down starting from the signature of Sudoku.Create you can infer from the sample above; reuse Theorem&amp;lt;T&amp;gt; of course).&lt;/p&gt;

&lt;p&gt;More complex puzzles exist though, for example a KenKen puzzle:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;a href="http://bartdesmet.net/images_wlw/LINQtoZ3TheoremSolvingonSteroidsPart1_12E1C/image_3.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://bartdesmet.net/images_wlw/LINQtoZ3TheoremSolvingonSteroidsPart1_12E1C/image_thumb_3.png" width="291" height="300" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Besides constraints on rows and columns and cells, similar to a Sudoku’s (with regards to the use of digits 1 through 4), there are more domain-specific constraints: all mathematical operators are commutative. For example, 1- in the two-cell region means that Cell12 – Cell22 or Cell22 – Cell12 equals to 1. For bigger regions all permutations of cells are considered. In other words, we need different semantics on operators. For example:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;k1 = &lt;span style="color:blue;"&gt;from &lt;/span&gt;t &lt;span style="color:blue;"&gt;in &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;KenKen4By4&lt;/span&gt;.Create(ctx)
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.Add(4, t.Cell11, t.Cell21)
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.Sub(1, t.Cell12, t.Cell22)
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.Mul(4, t.Cell13, t.Cell14, t.Cell23)
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.Mul(24, t.Cell31, t.Cell32, t.Cell33)
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.Sub(3, t.Cell24, t.Cell34)
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.Div(2, t.Cell41, t.Cell42)
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.Sub(1, t.Cell43, t.Cell44)
         &lt;span style="color:blue;"&gt;select &lt;/span&gt;t;
&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(k1.Solve());
&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine();&lt;/pre&gt;
  &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;results in the following constraints:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font face="Courier New"&gt;(and (&amp;lt;= 1 Cell11) (&amp;lt;= Cell11 4))
      &lt;br /&gt;(and (&amp;lt;= 1 Cell12) (&amp;lt;= Cell12 4))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell13) (&amp;lt;= Cell13 4))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell14) (&amp;lt;= Cell14 4))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell21) (&amp;lt;= Cell21 4))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell22) (&amp;lt;= Cell22 4))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell23) (&amp;lt;= Cell23 4))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell24) (&amp;lt;= Cell24 4))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell31) (&amp;lt;= Cell31 4))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell32) (&amp;lt;= Cell32 4))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell33) (&amp;lt;= Cell33 4))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell34) (&amp;lt;= Cell34 4))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell41) (&amp;lt;= Cell41 4))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell42) (&amp;lt;= Cell42 4))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell43) (&amp;lt;= Cell43 4))

      &lt;br /&gt;(and (&amp;lt;= 1 Cell44) (&amp;lt;= Cell44 4))

      &lt;br /&gt;(distinct Cell11 Cell12 Cell13 Cell14)

      &lt;br /&gt;(distinct Cell21 Cell22 Cell23 Cell24)

      &lt;br /&gt;(distinct Cell31 Cell32 Cell33 Cell34)

      &lt;br /&gt;(distinct Cell41 Cell42 Cell43 Cell44)

      &lt;br /&gt;(distinct Cell11 Cell21 Cell31 Cell41)

      &lt;br /&gt;(distinct Cell12 Cell22 Cell32 Cell42)

      &lt;br /&gt;(distinct Cell13 Cell23 Cell33 Cell43)

      &lt;br /&gt;(distinct Cell14 Cell24 Cell34 Cell44)

      &lt;br /&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;(= 4 (+ Cell11 Cell21))
          &lt;br /&gt;(or (= 1 (- Cell12 Cell22)) (= 1 (- Cell22 Cell12)))

          &lt;br /&gt;(= 4 (* (* Cell13 Cell14) Cell23))

          &lt;br /&gt;(= 24 (* (* Cell31 Cell32) Cell33))

          &lt;br /&gt;(or (= 3 (- Cell24 Cell34)) (= 3 (- Cell34 Cell24)))

          &lt;br /&gt;(or (= 2 (div Cell41 Cell42)) (= 2 (div Cell42 Cell41)))

          &lt;br /&gt;(or (= 1 (- Cell43 Cell44)) (= 1 (- Cell44 Cell43)))&lt;/strong&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Again the last set of constraints are a result of the LINQ query expression (as a side-note, different Z3 techniques are available to tackle problems, something outside the scope of this discussion just yet). In order to generate those constraints, the domain-specific Add, Sub, Mul and Div methods need to be translated into Z3 primitives, something that will be done by implementing a rewriter type (cf. the pieces of code I asked the reader to skim over for the time being). We could go one step further and allow the user to specify the puzzle by means of a visual textual DSL:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;k2 = &lt;span style="color:#2b91af;"&gt;KenKen4By4&lt;/span&gt;.Parse(ctx, &lt;span style="color:#a31515;"&gt;@&amp;quot;+#####+#####+#####+#####+
                                 # 4+  # 1-  # 4*        #
                                 +     +     +     +#####+
                                 #     #     #     # 3-  #
                                 +#####+#####+#####+     +
                                 # 24*             #     #
                                 +#####+#####+#####+#####+
                                 # 2/        # 1-        #
                                 +#####+#####+#####+#####+&amp;quot;&lt;/span&gt;);
&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(k2.Solve());
&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine();&lt;/pre&gt;
  &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;Or even consume the Word file (from which the screenshot of the puzzle was taken earlier) directly:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;k3 = &lt;span style="color:#2b91af;"&gt;KenKen4By4&lt;/span&gt;.FromWord(ctx, &lt;span style="color:#a31515;"&gt;@&amp;quot;C:\Users\Bart\Desktop\KenKen.docx&amp;quot;&lt;/span&gt;);
&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(k3.Solve());
&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine();&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;Finally there are Kakuro puzzles that give rise to yet another desire for better domain-specific theorem expressiveness:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;u1 = &lt;span style="color:blue;"&gt;from &lt;/span&gt;k &lt;span style="color:blue;"&gt;in &lt;/span&gt;ctx.NewTheorem&amp;lt;&lt;span style="color:#2b91af;"&gt;Kakuro&lt;/span&gt;&amp;gt;()
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell11.IsBlack
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell14.IsBlack
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell15.IsBlack
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell24.IsBlack
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell48.IsBlack
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell51.IsBlack
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell61.IsBlack
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell85.IsBlack
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell12.VerticalSum == 23
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell13.VerticalSum == 30
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell16.VerticalSum == 27
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell17.VerticalSum == 12
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell18.VerticalSum == 16
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell21.HorizontalSum == 16
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell25.VerticalSum == 17
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell25.HorizontalSum == 24
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell31.HorizontalSum == 17
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell34.VerticalSum == 15
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell34.HorizontalSum == 29
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell41.HorizontalSum == 35
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell47.VerticalSum == 12
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell52.HorizontalSum == 7
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell55.VerticalSum == 7
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell55.HorizontalSum == 8
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell58.VerticalSum == 7
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell62.VerticalSum == 11
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell63.VerticalSum == 10
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell63.HorizontalSum == 16
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell71.HorizontalSum == 21
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell76.HorizontalSum == 5
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell81.HorizontalSum == 6
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell86.HorizontalSum == 3
         &lt;span style="color:blue;"&gt;select &lt;/span&gt;k;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here properties are used to indicate constraints as simple as possible, for the following puzzle:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font face="Courier New"&gt;+--------+--------+--------+--------+--------+--------+--------+--------+
      &lt;br /&gt;| ****** | 23&amp;#160;&amp;#160;&amp;#160;&amp;#160; | 30&amp;#160;&amp;#160;&amp;#160;&amp;#160; | ****** | ****** | 27&amp;#160;&amp;#160;&amp;#160;&amp;#160; | 12&amp;#160;&amp;#160;&amp;#160;&amp;#160; | 16&amp;#160;&amp;#160;&amp;#160;&amp;#160; |

      &lt;br /&gt;+--------+--------+--------+--------+--------+--------+--------+--------+

      &lt;br /&gt;|&amp;#160;&amp;#160;&amp;#160;&amp;#160; 16 |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; | ****** | 17&amp;#160; 24 |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |

      &lt;br /&gt;+--------+--------+--------+--------+--------+--------+--------+--------+

      &lt;br /&gt;|&amp;#160;&amp;#160;&amp;#160;&amp;#160; 17 |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; | 15&amp;#160; 29 |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |

      &lt;br /&gt;+--------+--------+--------+--------+--------+--------+--------+--------+

      &lt;br /&gt;|&amp;#160;&amp;#160;&amp;#160;&amp;#160; 35 |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; | 12&amp;#160;&amp;#160;&amp;#160;&amp;#160; | ****** |

      &lt;br /&gt;+--------+--------+--------+--------+--------+--------+--------+--------+

      &lt;br /&gt;| ****** |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 7 |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; | 7&amp;#160;&amp;#160;&amp;#160; 8 |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; | 7&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |

      &lt;br /&gt;+--------+--------+--------+--------+--------+--------+--------+--------+

      &lt;br /&gt;| ****** | 11&amp;#160;&amp;#160;&amp;#160;&amp;#160; | 10&amp;#160; 16 |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |

      &lt;br /&gt;+--------+--------+--------+--------+--------+--------+--------+--------+

      &lt;br /&gt;|&amp;#160;&amp;#160;&amp;#160;&amp;#160; 21 |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 5 |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |

      &lt;br /&gt;+--------+--------+--------+--------+--------+--------+--------+--------+

      &lt;br /&gt;|&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 6 |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; | ****** |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 3 |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |

      &lt;br /&gt;+--------+--------+--------+--------+--------+--------+--------+--------+&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We don’t want the user to express things like Cell22 + Cell32 + Cell42 == 23, but instead want to use all the information captured in the puzzle to allow constraints like Cell12.VerticalSum == 23. As we’ll see, this requires other rewriting mechanisms to allow for a good balance of responsibilities between:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The LINQ to Z3 infrastructure.&lt;/li&gt;

  &lt;li&gt;The Kakuro puzzle library writer.&lt;/li&gt;

  &lt;li&gt;The end-user.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The resulting Z3 constraints for the sample puzzle are shown below:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font face="Courier New"&gt;(and &lt;strong&gt;&lt;font color="#ff0000"&gt;(= (+ (+ Cell22 Cell32) Cell42) 23)&lt;/font&gt;&lt;/strong&gt; (distinct Cell22 Cell32 Cell42))

      &lt;br /&gt;(and &lt;strong&gt;&lt;font color="#ff0000"&gt;(= (+ (+ (+ Cell23 Cell33) Cell43) Cell53) 30)&lt;/font&gt;&lt;/strong&gt;

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (distinct Cell23 Cell33 Cell43 Cell53))

      &lt;br /&gt;(and &lt;strong&gt;&lt;font color="#ff0000"&gt;(= (+ (+ (+ (+ Cell26 Cell36) Cell46) Cell56) Cell66) 27)
          &lt;br /&gt;&lt;/font&gt;&lt;/strong&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (distinct Cell26 Cell36 Cell46 Cell56 Cell66))

      &lt;br /&gt;(and &lt;strong&gt;&lt;font color="#ff0000"&gt;(= (+ Cell27 Cell37) 12)&lt;/font&gt;&lt;/strong&gt; (distinct Cell27 Cell37))

      &lt;br /&gt;(and &lt;strong&gt;&lt;font color="#ff0000"&gt;(= (+ Cell28 Cell38) 16)&lt;/font&gt;&lt;/strong&gt; (distinct Cell28 Cell38))

      &lt;br /&gt;(and &lt;strong&gt;&lt;font color="#ff0000"&gt;(= (+ Cell22 Cell23) 16)&lt;/font&gt;&lt;/strong&gt; (distinct Cell22 Cell23))

      &lt;br /&gt;(and (&amp;gt;= Cell22 1) (&amp;lt;= Cell22 9))

      &lt;br /&gt;(and (&amp;gt;= Cell23 1) (&amp;lt;= Cell23 9))

      &lt;br /&gt;(and &lt;strong&gt;&lt;font color="#ff0000"&gt;(= (+ (+ Cell26 Cell27) Cell28) 24)&lt;/font&gt;&lt;/strong&gt; (distinct Cell26 Cell27 Cell28))

      &lt;br /&gt;(and &lt;strong&gt;&lt;font color="#ff0000"&gt;(= (+ Cell35 Cell45) 17)&lt;/font&gt;&lt;/strong&gt; (distinct Cell35 Cell45))

      &lt;br /&gt;(and (&amp;gt;= Cell26 1) (&amp;lt;= Cell26 9))

      &lt;br /&gt;(and (&amp;gt;= Cell27 1) (&amp;lt;= Cell27 9))

      &lt;br /&gt;(and (&amp;gt;= Cell28 1) (&amp;lt;= Cell28 9))

      &lt;br /&gt;(and &lt;strong&gt;&lt;font color="#ff0000"&gt;(= (+ Cell32 Cell33) 17)&lt;/font&gt;&lt;/strong&gt; (distinct Cell32 Cell33))

      &lt;br /&gt;(and (&amp;gt;= Cell32 1) (&amp;lt;= Cell32 9))

      &lt;br /&gt;(and (&amp;gt;= Cell33 1) (&amp;lt;= Cell33 9))

      &lt;br /&gt;(and &lt;strong&gt;&lt;font color="#ff0000"&gt;(= (+ (+ (+ Cell35 Cell36) Cell37) Cell38) 29)
          &lt;br /&gt;&lt;/font&gt;&lt;/strong&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (distinct Cell35 Cell36 Cell37 Cell38))

      &lt;br /&gt;(and &lt;strong&gt;&lt;font color="#ff0000"&gt;(= (+ (+ (+ (+ Cell44 Cell54) Cell64) Cell74) Cell84) 15)&lt;/font&gt;&lt;/strong&gt;

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (distinct Cell44 Cell54 Cell64 Cell74 Cell84))

      &lt;br /&gt;(and (&amp;gt;= Cell35 1) (&amp;lt;= Cell35 9))

      &lt;br /&gt;(and (&amp;gt;= Cell36 1) (&amp;lt;= Cell36 9))

      &lt;br /&gt;(and (&amp;gt;= Cell37 1) (&amp;lt;= Cell37 9))

      &lt;br /&gt;(and (&amp;gt;= Cell38 1) (&amp;lt;= Cell38 9))

      &lt;br /&gt;(and &lt;strong&gt;&lt;font color="#ff0000"&gt;(= (+ (+ (+ (+ Cell42 Cell43) Cell44) Cell45) Cell46) 35)
          &lt;br /&gt;&lt;/font&gt;&lt;/strong&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (distinct Cell42 Cell43 Cell44 Cell45 Cell46))

      &lt;br /&gt;(and (&amp;gt;= Cell42 1) (&amp;lt;= Cell42 9))

      &lt;br /&gt;(and (&amp;gt;= Cell43 1) (&amp;lt;= Cell43 9))

      &lt;br /&gt;(and (&amp;gt;= Cell44 1) (&amp;lt;= Cell44 9))

      &lt;br /&gt;(and (&amp;gt;= Cell45 1) (&amp;lt;= Cell45 9))

      &lt;br /&gt;(and (&amp;gt;= Cell46 1) (&amp;lt;= Cell46 9))

      &lt;br /&gt;(and &lt;/font&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;(= (+ (+ (+ Cell57 Cell67) Cell77) Cell87) 12)&lt;/font&gt;&lt;/strong&gt;

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (distinct Cell57 Cell67 Cell77 Cell87))

      &lt;br /&gt;(and &lt;strong&gt;&lt;font color="#ff0000"&gt;(= (+ Cell53 Cell54) 7)&lt;/font&gt;&lt;/strong&gt; (distinct Cell53 Cell54))

      &lt;br /&gt;(and (&amp;gt;= Cell53 1) (&amp;lt;= Cell53 9))

      &lt;br /&gt;(and (&amp;gt;= Cell54 1) (&amp;lt;= Cell54 9))

      &lt;br /&gt;(and &lt;strong&gt;&lt;font color="#ff0000"&gt;(= (+ Cell56 Cell57) 8)&lt;/font&gt;&lt;/strong&gt; (distinct Cell56 Cell57))

      &lt;br /&gt;(and &lt;strong&gt;&lt;font color="#ff0000"&gt;(= (+ Cell65 Cell75) 7)&lt;/font&gt;&lt;/strong&gt; (distinct Cell65 Cell75))

      &lt;br /&gt;(and (&amp;gt;= Cell56 1) (&amp;lt;= Cell56 9))

      &lt;br /&gt;(and (&amp;gt;= Cell57 1) (&amp;lt;= Cell57 9))

      &lt;br /&gt;(and &lt;strong&gt;&lt;font color="#ff0000"&gt;(= (+ (+ Cell68 Cell78) Cell88) 7)&lt;/font&gt;&lt;/strong&gt; (distinct Cell68 Cell78 Cell88))

      &lt;br /&gt;(and &lt;strong&gt;&lt;font color="#ff0000"&gt;(= (+ Cell72 Cell82) 11)&lt;/font&gt; &lt;/strong&gt;(distinct Cell72 Cell82))

      &lt;br /&gt;(and &lt;/font&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;(= (+ (+ (+ (+ Cell64 Cell65) Cell66) Cell67) Cell68) 16)
          &lt;br /&gt;&lt;/font&gt;&lt;/strong&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (distinct Cell64 Cell65 Cell66 Cell67 Cell68))

      &lt;br /&gt;(and &lt;strong&gt;&lt;font color="#ff0000"&gt;(= (+ Cell73 Cell83) 10)&lt;/font&gt;&lt;/strong&gt; (distinct Cell73 Cell83))

      &lt;br /&gt;(and (&amp;gt;= Cell64 1) (&amp;lt;= Cell64 9))

      &lt;br /&gt;(and (&amp;gt;= Cell65 1) (&amp;lt;= Cell65 9))

      &lt;br /&gt;(and (&amp;gt;= Cell66 1) (&amp;lt;= Cell66 9))

      &lt;br /&gt;(and (&amp;gt;= Cell67 1) (&amp;lt;= Cell67 9))

      &lt;br /&gt;(and (&amp;gt;= Cell68 1) (&amp;lt;= Cell68 9))

      &lt;br /&gt;(and &lt;font color="#ff0000"&gt;&lt;strong&gt;(= (+ (+ (+ Cell72 Cell73) Cell74) Cell75) 21)&lt;/strong&gt;

        &lt;br /&gt;&lt;/font&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (distinct Cell72 Cell73 Cell74 Cell75))

      &lt;br /&gt;(and (&amp;gt;= Cell72 1) (&amp;lt;= Cell72 9))

      &lt;br /&gt;(and (&amp;gt;= Cell73 1) (&amp;lt;= Cell73 9))

      &lt;br /&gt;(and (&amp;gt;= Cell74 1) (&amp;lt;= Cell74 9))

      &lt;br /&gt;(and (&amp;gt;= Cell75 1) (&amp;lt;= Cell75 9))

      &lt;br /&gt;(and &lt;strong&gt;&lt;font color="#ff0000"&gt;(= (+ Cell77 Cell78) 5)&lt;/font&gt;&lt;/strong&gt; (distinct Cell77 Cell78))

      &lt;br /&gt;(and (&amp;gt;= Cell77 1) (&amp;lt;= Cell77 9))

      &lt;br /&gt;(and (&amp;gt;= Cell78 1) (&amp;lt;= Cell78 9))

      &lt;br /&gt;(and &lt;strong&gt;&lt;font color="#ff0000"&gt;(= (+ (+ Cell82 Cell83) Cell84) 6)&lt;/font&gt;&lt;/strong&gt; (distinct Cell82 Cell83 Cell84))

      &lt;br /&gt;(and (&amp;gt;= Cell82 1) (&amp;lt;= Cell82 9))

      &lt;br /&gt;(and (&amp;gt;= Cell83 1) (&amp;lt;= Cell83 9))

      &lt;br /&gt;(and (&amp;gt;= Cell84 1) (&amp;lt;= Cell84 9))

      &lt;br /&gt;(and &lt;strong&gt;&lt;font color="#ff0000"&gt;(= (+ Cell87 Cell88) 3)&lt;/font&gt;&lt;/strong&gt; (distinct Cell87 Cell88))

      &lt;br /&gt;(and (&amp;gt;= Cell87 1) (&amp;lt;= Cell87 9))

      &lt;br /&gt;(and (&amp;gt;= Cell88 1) (&amp;lt;= Cell88 9))&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Again the red parts reflect what the user expressed, while the remainder is all generated by the domain-specific Kakuro implementation.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h1&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/h1&gt;

&lt;p&gt;Creating a simple LINQ to Z3 implementation isn’t too hard and involves just a little bit of plumbing in the bathroom of reflection and some use of expression tree visitor patterns. In future posts, we’ll have a look at domain-specific theorem solving techniques based on declarative expression tree rewriters. Enjoy!&lt;/p&gt;&lt;img src="http://bartdesmet.net/aggbug.aspx?PostID=14829" width="1" height="1"&gt;</description><category domain="http://bartdesmet.net/blogs/bart/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://bartdesmet.net/blogs/bart/archive/tags/Crazy+Sundays/default.aspx">Crazy Sundays</category><category domain="http://bartdesmet.net/blogs/bart/archive/tags/Z3/default.aspx">Z3</category><category domain="http://bartdesmet.net/blogs/bart/archive/tags/Microsoft+Research/default.aspx">Microsoft Research</category></item><item><title>LINQ to Z3 – Theorem Solving on Steroids – Part 0</title><link>http://bartdesmet.net/blogs/bart/archive/2009/04/19/linq-to-z3-theorem-solving-on-steroids-part-0.aspx</link><pubDate>Sun, 19 Apr 2009 22:31:27 GMT</pubDate><guid isPermaLink="false">863c5522-913f-4a64-ac0a-bd5f05abad0f:14410</guid><dc:creator>bart</dc:creator><slash:comments>16</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://bartdesmet.net/blogs/bart/rsscomments.aspx?PostID=14410</wfw:commentRss><comments>http://bartdesmet.net/blogs/bart/archive/2009/04/19/linq-to-z3-theorem-solving-on-steroids-part-0.aspx#comments</comments><description>&lt;h1&gt;Introduction&lt;/h1&gt;  &lt;p&gt;&lt;a href="http://community.bartdesmet.net/blogs/bart/archive/2009/04/15/exploring-the-z3-theorem-prover-with-a-bit-of-linq.aspx"&gt;Last time around&lt;/a&gt; in this blog category we looked at using Z3 for testing satisfiability of simple Boolean logic expressions. Obviously Z3 is capable of doing much more, so this time we’ll reach out to the domain of integer value arithmetic. Not only that, last time I subtly hinted how this story could continue … with “a bit of LINQ”. So I’m very happy to present to you today an “esoteric LINQ binding” implementation: LINQ to Z3.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Esoteric LINQ bindings&lt;/h1&gt;  &lt;p&gt;According to the &lt;a href="http://www.merriam-webster.com/dictionary/esoteric"&gt;Merriam-Webster Online Dictionary&lt;/a&gt;, “estoric” means:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;1 a&lt;strong&gt;:&lt;/strong&gt; designed for or understood by the specially initiated alone &amp;lt;a body of &lt;em&gt;esoteric&lt;/em&gt; legal doctrine — B. N. Cardozo&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160; b&lt;strong&gt;:&lt;/strong&gt; requiring or exhibiting knowledge that is restricted to a small group &amp;lt;&lt;em&gt;esoteric&lt;/em&gt; terminology&amp;gt; ; &lt;em&gt;broadly&lt;/em&gt; &lt;strong&gt;:&lt;/strong&gt; difficult to understand &amp;lt;&lt;em&gt;esoteric&lt;/em&gt; subjects&amp;gt;      &lt;br /&gt;2 a&lt;strong&gt;:&lt;/strong&gt; limited to a small circle &amp;lt;engaging in &lt;em&gt;esoteric&lt;/em&gt; pursuits&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160; b&lt;strong&gt;:&lt;/strong&gt; &lt;a href="http://www.merriam-webster.com/private"&gt;private&lt;/a&gt;, &lt;a href="http://www.merriam-webster.com/confidential"&gt;confidential&lt;/a&gt; &amp;lt;an &lt;em&gt;esoteric&lt;/em&gt; purpose&amp;gt;      &lt;br /&gt;3&lt;strong&gt;:&lt;/strong&gt; of special, rare, or unusual interest &amp;lt;&lt;em&gt;esoteric&lt;/em&gt; building materials&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;While point 1 might be true (but you’ll only know for sure after reading this and subsequent posts), I’ll try to avoid it where possible: LINQ is a democracy after all. Point 2 has been true before the publication of this post, but as I’m writing this it becomes invalid: LINQ to Z3 for the masses. The final point is maybe the most accurate: “of special, rare, or unusual interest”.&lt;/p&gt;  &lt;p&gt;Therefore I’d define esoteric LINQ bindings as “LINQ to the unexpected”. Most people live in the mindset of LINQ providers reaching out to “some collection of data locally or remotely”, in the IEnumerable&amp;lt;T&amp;gt; or IQueryable&amp;lt;T&amp;gt; sense of the word. Nothing is further away from the truth; LINQ is nothing more than a syntactical pattern that glues things – operators that is – together in a syntactically silent (as opposed to noisy) way. I sometimes use this comparison in my “LINQ in Breadth” talks:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://bartdesmet.info/images_wlw/LINQtoZ3TheoremSolvingonSteroidsPart0_145BC/image.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://bartdesmet.info/images_wlw/LINQtoZ3TheoremSolvingonSteroidsPart0_145BC/image_thumb.png" width="640" height="425" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;What I’m talking about in the context of “esoteric LINQ bindings” is the Syntactose part – the use of language integrated keywords that reduce the noise that would be imposed on the developer otherwise:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;from &lt;/font&gt;x &lt;font color="#0000ff"&gt;in &lt;/font&gt;y &lt;font color="#0000ff"&gt;where &lt;/font&gt;x.Bar == 123 &lt;font color="#0000ff"&gt;select &lt;/font&gt;x;&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;becomes (and yes, &lt;em&gt;in this case &lt;/em&gt;&lt;a href="http://community.bartdesmet.net/blogs/bart/archive/2008/08/20/what-do-vb-9-0-error-bc36593-expression-of-type-x-is-not-queryable-and-c-3-0-error-cs1936-could-not-find-an-implementation-of-the-query-pattern-for-source-type-x-really-mean.aspx"&gt;the select just falls away&lt;/a&gt;):&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;y.Where&lt;font color="#ff0000"&gt;(x =&amp;gt; &lt;/font&gt;x.Bar == 123&lt;font color="#ff0000"&gt;)&lt;/font&gt;;&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Look how much noise (indicated in red) goes away. But what’s even more important is that the lambda expressions used in the queries can be translated into gigantic expressions trees to open up for runtime code-as-data inspection. In the world of C# 2.0, the above might have looked as ugly as this:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#008080"&gt;ParameterExpression &lt;/font&gt;x = &lt;font color="#008080"&gt;Expression&lt;/font&gt;.Parameter(&lt;font color="#0000ff"&gt;typeof&lt;/font&gt;(&lt;font color="#008080"&gt;Demo&lt;/font&gt;), &lt;font color="#800000"&gt;“x”&lt;/font&gt;);        &lt;br /&gt;&lt;font color="#008080"&gt;Extensions&lt;/font&gt;.Where(y, &lt;font color="#008080"&gt;Expression&lt;/font&gt;.Lambda(&lt;font color="#008080"&gt;Expression&lt;/font&gt;.Equal(&lt;font color="#008080"&gt;Expression&lt;/font&gt;.Property(x, &lt;font color="#0000ff"&gt;typeof&lt;/font&gt;(&lt;font color="#008080"&gt;Demo&lt;/font&gt;).GetProperty(&lt;font color="#800000"&gt;“Bar”&lt;/font&gt;)), &lt;font color="#008080"&gt;Expression&lt;/font&gt;.Constant(123)), x));&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;You’ll agree that’s not very readable. So in essence, the LINQ syntax is a very convenient gateway to simple meta-programming facilities where expression trees play a central role. And the target of such “queries” is not necessarily some persistent data store. The sky is the limit and that’s what we exploit in esoteric LINQ bindings.&lt;/p&gt;  &lt;p&gt;Notice I’m speaking about “bindings” not “providers”, the latter term being reserved for “query providers” typically (but not necessarily) in the IQueryProvider sense.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Our mission&lt;/h1&gt;  &lt;p&gt;With LINQ to Z3 my goal is to abstract away from the low-level Z3 APIs and provide nice syntax with rich static typing support on top of it. The basic idea is the following:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Define the “shape” of a theorem, e.g. what symbolic names (and their types) to use;&lt;/li&gt;    &lt;li&gt;Express constraints over those symbolic names using LINQ syntax (more specifically the where keyword);&lt;/li&gt;    &lt;li&gt;Ask the resulting object for a solution, resulting in an instance of the “shape” type specified at the start.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;An example:&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;theorem = &lt;span style="color:blue;"&gt;from &lt;/span&gt;t &lt;span style="color:blue;"&gt;in &lt;/span&gt;ctx.NewTheorem&amp;lt;&lt;span style="color:#2b91af;"&gt;Symbols&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt;&amp;gt;()
              &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.X1 - t.X2 &amp;gt;= 1
              &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.X1 - t.X2 &amp;lt;= 3
              &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.X1 == (2 * t.X3) + t.X5
              &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.X3 == t.X5
              &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.X2 == 6 * t.X4
              &lt;span style="color:blue;"&gt;select &lt;/span&gt;t;
&lt;span style="color:blue;"&gt;var &lt;/span&gt;solution = theorem.Solve();
&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;X1 = {0}, X2 = {1}, X3 = {2}, X4 = {3}, X5 = {4}&amp;quot;&lt;/span&gt;, solution.X1, solution.X2, solution.X3, solution.X4, solution.X5);&lt;/pre&gt;
  &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;In here ctx stands for a Z3Context object that can be used to do logging of the internal Z3 expressions being generated by the binding (just like *DataContext is used in LINQ to *). We ask the context to new up a Theorem&amp;lt;T&amp;gt; by calling NewTheorem&amp;lt;T&amp;gt;. Here we use a canned generic Symbols type that has five symbolic names (expressed as properties), each of which are typed to be int in this case.&lt;/p&gt;

&lt;p&gt;When writing the LINQ query over this we get full IntelliSense and static typing:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;a href="http://bartdesmet.info/images_wlw/LINQtoZ3TheoremSolvingonSteroidsPart0_145BC/image_3.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://bartdesmet.info/images_wlw/LINQtoZ3TheoremSolvingonSteroidsPart0_145BC/image_thumb_3.png" width="602" height="214" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Finally we invoke the Solve method on the theorem; notice our “LINQ expression” is therefore lazy, just like “regular” LINQ expressions are. This also means theorems are composable; we could refine the theorem above by writing one or more query expressions over the existing one:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;stronger = &lt;span style="color:blue;"&gt;from &lt;/span&gt;t &lt;span style="color:blue;"&gt;in &lt;/span&gt;theorem
               &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.X4 &amp;gt; 0
               &lt;span style="color:blue;"&gt;select &lt;/span&gt;t;&lt;/pre&gt;
  &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;The Solve&amp;lt;T&amp;gt; method returns an instance of T, where T in our sample stands for the Symbols&amp;lt;int, …, int&amp;gt; generic type, so we can print the results to the screen:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;a href="http://bartdesmet.info/images_wlw/LINQtoZ3TheoremSolvingonSteroidsPart0_145BC/image_4.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://bartdesmet.info/images_wlw/LINQtoZ3TheoremSolvingonSteroidsPart0_145BC/image_thumb_4.png" width="356" height="92" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As I’ve enabled logging, you can see the Z3 expressions that were translated from the query expression. You can verify the result printed on the last line satisfies the constraints of the theorem, with many thanks to the Z3 engine.&lt;/p&gt;

&lt;p&gt;Ultimately we even want to express more complex theorem solving domains, completely statically typed, over LINQ to Z3. Examples include solving puzzles like Sudoku, Kakuro, KenKen, etc. The sample below illustrates a LINQ query used to solve a &lt;a href="http://en.wikipedia.org/wiki/Kakuro"&gt;Kakuro puzzle&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;u1 = &lt;span style="color:blue;"&gt;from &lt;/span&gt;k &lt;span style="color:blue;"&gt;in &lt;/span&gt;ctx.NewTheorem&amp;lt;&lt;span style="color:#2b91af;"&gt;Kakuro&lt;/span&gt;&amp;gt;()
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell11.IsBlack
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell14.IsBlack
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell15.IsBlack
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell24.IsBlack
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell48.IsBlack
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell51.IsBlack
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell61.IsBlack
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell85.IsBlack
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell12.VerticalSum == 23
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell13.VerticalSum == 30
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell16.VerticalSum == 27
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell17.VerticalSum == 12
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell18.VerticalSum == 16
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell21.HorizontalSum == 16
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell25.VerticalSum == 17
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell25.HorizontalSum == 24
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell31.HorizontalSum == 17
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell34.VerticalSum == 15
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell34.HorizontalSum == 29
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell41.HorizontalSum == 35
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell47.VerticalSum == 12
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell52.HorizontalSum == 7
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell55.VerticalSum == 7
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell55.HorizontalSum == 8
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell58.VerticalSum == 7
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell62.VerticalSum == 11
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell63.VerticalSum == 10
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell63.HorizontalSum == 16
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell71.HorizontalSum == 21
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell76.HorizontalSum == 5
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell81.HorizontalSum == 6
         &lt;span style="color:blue;"&gt;where &lt;/span&gt;k.Cell86.HorizontalSum == 3
         &lt;span style="color:blue;"&gt;select &lt;/span&gt;k;&lt;/pre&gt;
  &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;The textual representation of this Kakuro is shown below:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font face="Courier New"&gt;+--------+--------+--------+--------+--------+--------+--------+--------+
      &lt;br /&gt;| ****** | 23&amp;#160;&amp;#160;&amp;#160;&amp;#160; | 30&amp;#160;&amp;#160;&amp;#160;&amp;#160; | ****** | ****** | 27&amp;#160;&amp;#160;&amp;#160;&amp;#160; | 12&amp;#160;&amp;#160;&amp;#160;&amp;#160; | 16&amp;#160;&amp;#160;&amp;#160;&amp;#160; |

      &lt;br /&gt;+--------+--------+--------+--------+--------+--------+--------+--------+

      &lt;br /&gt;|&amp;#160;&amp;#160;&amp;#160;&amp;#160; 16 |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; | ****** | 17&amp;#160; 24 |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |

      &lt;br /&gt;+--------+--------+--------+--------+--------+--------+--------+--------+

      &lt;br /&gt;|&amp;#160;&amp;#160;&amp;#160;&amp;#160; 17 |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; | 15&amp;#160; 29 |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |

      &lt;br /&gt;+--------+--------+--------+--------+--------+--------+--------+--------+

      &lt;br /&gt;|&amp;#160;&amp;#160;&amp;#160;&amp;#160; 35 |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; | 12&amp;#160;&amp;#160;&amp;#160;&amp;#160; | ****** |

      &lt;br /&gt;+--------+--------+--------+--------+--------+--------+--------+--------+

      &lt;br /&gt;| ****** |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 7 |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; | 7&amp;#160;&amp;#160;&amp;#160; 8 |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; | 7&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |

      &lt;br /&gt;+--------+--------+--------+--------+--------+--------+--------+--------+

      &lt;br /&gt;| ****** | 11&amp;#160;&amp;#160;&amp;#160;&amp;#160; | 10&amp;#160; 16 |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |

      &lt;br /&gt;+--------+--------+--------+--------+--------+--------+--------+--------+

      &lt;br /&gt;|&amp;#160;&amp;#160;&amp;#160;&amp;#160; 21 |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 5 |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |

      &lt;br /&gt;+--------+--------+--------+--------+--------+--------+--------+--------+

      &lt;br /&gt;|&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 6 |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; | ****** |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 3 |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |

      &lt;br /&gt;+--------+--------+--------+--------+--------+--------+--------+--------+&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And here’s the output of our solver tackling the theorem. Notice the amount of constraints (it scrolls up!) inferred from this purely declarative Kakuro specification using LINQ:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;a href="http://bartdesmet.info/images_wlw/LINQtoZ3TheoremSolvingonSteroidsPart0_145BC/image_5.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://bartdesmet.info/images_wlw/LINQtoZ3TheoremSolvingonSteroidsPart0_145BC/image_thumb_5.png" width="677" height="858" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;By the end of this series you’ll know exactly how all of this works. We’ll go even more crazy and use MGrammar to parse textual representations of puzzles like Kakuro to turn them into an executable piece of code that dynamically builds up LINQ expression trees that are then fed to LINQ to Z3 in order to be solved. And, for the Sudoku and KenKen puzzles we’ll read the specification from regular Word tables:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;a href="http://bartdesmet.info/images_wlw/LINQtoZ3TheoremSolvingonSteroidsPart0_145BC/image_6.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://bartdesmet.info/images_wlw/LINQtoZ3TheoremSolvingonSteroidsPart0_145BC/image_thumb_6.png" width="458" height="616" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yes, we’ll “execute” the document above to solve the KenKen puzzle inside it using Z3:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;var &lt;/span&gt;k3 = &lt;span style="color:#2b91af;"&gt;KenKen4By4&lt;/span&gt;.FromWord(ctx, &lt;span style="color:#a31515;"&gt;@&amp;quot;C:\Users\Bart\Desktop\KenKen.docx&amp;quot;&lt;/span&gt;);
&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(k3.Solve());
&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine();&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;and here’s the verbose logging output with the result printed at the bottom:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;a href="http://bartdesmet.info/images_wlw/LINQtoZ3TheoremSolvingonSteroidsPart0_145BC/image_7.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://bartdesmet.info/images_wlw/LINQtoZ3TheoremSolvingonSteroidsPart0_145BC/image_thumb_7.png" width="677" height="474" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Word-to-KenKen-to-LINQ-to-Z3 that is: composability pushed to its limits. But let’s try to walk before we start running; first things first: the query pattern.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h1&gt;The LINQ to Z3 query pattern&lt;/h1&gt;

&lt;p&gt;Today we’ll have a look at how we establish the query pattern with all IntelliSense while writing the query expression. As we’ve seen before, all we need is the where operator to add constraints to a theorem. But before we can go there, we need to know how to represent a Theorem type. Every theorem has a variable number of symbols it puts constraints on: some theorem might have two Boolean symbols, another might have five integer values, or any mix of the two. There are more types the theorem prover can deal with, such as uninterpreted functions, but to keep things simple we’ll omit those for now.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Instantiating Theorem objects – Option 1&lt;/h2&gt;

&lt;p&gt;In order for the user to declare the “environment” of a theorem, i.e. the symbols and their types, we can take two different approaches. One is based on nominal types, where the user creates a Theorem&amp;lt;T&amp;gt; with T being a type that has the environment defined as a set of properties or so:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;class &lt;/font&gt;&lt;font color="#008080"&gt;TwoBools&lt;/font&gt;

      &lt;br /&gt;{

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#0000ff"&gt;public bool &lt;/font&gt;x { &lt;font color="#0000ff"&gt;get&lt;/font&gt;; &lt;font color="#0000ff"&gt;set&lt;/font&gt;; }

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#0000ff"&gt;public bool &lt;/font&gt;y { &lt;font color="#0000ff"&gt;get&lt;/font&gt;; &lt;font color="#0000ff"&gt;set&lt;/font&gt;; }

      &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I’m violating the design guidelines by having properties that do not begin with a capital letter (Pascal-casing), as theorem variables have a mathematical meaning.&lt;/p&gt;

&lt;p&gt;But having to define such types every time you want to write a theorem can be painful, so we want more convenient ways to set the scene. One approach is to have a couple of canned generic types with 1 to x number of symbols pre-defined using generic parameter, likeso:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color:green;"&gt;Pre-defined enviroment with three symbols.
&lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;typeparam name=&amp;quot;T1&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Type of the first symbol.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
/// &amp;lt;typeparam name=&amp;quot;T2&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Type of the second symbol.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
/// &amp;lt;typeparam name=&amp;quot;T3&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Type of the third symbol.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
&lt;/span&gt;&lt;span style="color:blue;"&gt;public sealed class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Symbols&lt;/span&gt;&amp;lt;T1, T2, T3&amp;gt; : &lt;span style="color:#2b91af;"&gt;Symbols
&lt;/span&gt;{
    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Provides access to the first symbol.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;remarks&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Used within definition of theorem constraints and to print the theorem prover&amp;#39;s result.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/remarks&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;T1 X1 { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;private set&lt;/span&gt;; }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Provides access to the second symbol.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;remarks&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Used within definition of theorem constraints and to print the theorem prover&amp;#39;s result.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/remarks&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;T2 X2 { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;private set&lt;/span&gt;; }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Provides access to the third symbol.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;remarks&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Used within definition of theorem constraints and to print the theorem prover&amp;#39;s result.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/remarks&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;T3 X3 { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;private set&lt;/span&gt;; }
}&lt;/pre&gt;
  &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;The base type simply overrides ToString to provide pretty printing of all the type’s properties:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color:green;"&gt;Base class for symbol container types.
&lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
&lt;/span&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Symbols
&lt;/span&gt;{
    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Returns a friendly representation of the symbols and their values.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &lt;/span&gt;&lt;span style="color:green;"&gt;Used to print the output of a theorem solving task.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Friendly representation of the symbols and their values.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public override string &lt;/span&gt;ToString()
    {
        &lt;span style="color:blue;"&gt;var &lt;/span&gt;propertyValues = &lt;span style="color:blue;"&gt;from &lt;/span&gt;prop &lt;span style="color:blue;"&gt;in &lt;/span&gt;GetType().GetProperties()
                             &lt;span style="color:blue;"&gt;let &lt;/span&gt;value = prop.GetValue(&lt;span style="color:blue;"&gt;this&lt;/span&gt;, &lt;span style="color:blue;"&gt;null&lt;/span&gt;)
                             &lt;span style="color:blue;"&gt;select &lt;/span&gt;prop.Name + &lt;span style="color:#a31515;"&gt;&amp;quot; = &amp;quot; &lt;/span&gt;+ (value ?? &lt;span style="color:#a31515;"&gt;&amp;quot;(null)&amp;quot;&lt;/span&gt;);
        &lt;span style="color:blue;"&gt;return &lt;/span&gt;&lt;span style="color:#a31515;"&gt;&amp;quot;{&amp;quot; &lt;/span&gt;+ &lt;span style="color:blue;"&gt;string&lt;/span&gt;.Join(&lt;span style="color:#a31515;"&gt;&amp;quot;, &amp;quot;&lt;/span&gt;, propertyValues.ToArray()) + &lt;span style="color:#a31515;"&gt;&amp;quot;}&amp;quot;&lt;/span&gt;;
    }
}&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;While this is already a bit more convenient, it still gets quite verbose and the symbol names are fixed, not quite aligning with the theorem to be expressed:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;font color="#0000ff"&gt;var&lt;/font&gt; theo = &lt;span style="color:blue;"&gt;from &lt;/span&gt;t &lt;span style="color:blue;"&gt;in &lt;/span&gt;ctx.NewTheorem&amp;lt;&lt;span style="color:#2b91af;"&gt;Symbols&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt;&amp;gt;()
           &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.X1 - t.X2 &amp;gt;= 1
           &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.X1 - t.X2 &amp;lt;= 3
           &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.X1 == (2 * t.X3) + t.X5
           &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.X3 == t.X5
           &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.X2 == 6 * t.X4
           &lt;span style="color:blue;"&gt;select &lt;/span&gt;t);&lt;/pre&gt;
  &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;Maybe the names X1 to X5 are quite accurate here but we need any number of generic Symbols&amp;lt;…&amp;gt; types (for a Sudoku we’d need one with 81 parameters, and X10 would stand for second row, first column, kind of ugly), so we’d also like to be able to use C#’s capability to create anonymous types (which are somewhat the opposite of nominal types, although they’re not quite structural either – the CLR doesn’t have structural typing after all – so let’s just continue to call them anonymous types because that’s what they are :-)) on the fly.&lt;/p&gt;

&lt;p&gt;So, instead of specifying a type by its name, we’d like to be able to specify the skeleton “inline”:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font face="Courier New"&gt;ctx.NewTheorem&amp;lt;&lt;font color="#0000ff"&gt;class &lt;/font&gt;{ &lt;font color="#0000ff"&gt;int &lt;/font&gt;X; &lt;font color="#0000ff"&gt;int &lt;/font&gt;Y; }&amp;gt;&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;doesn’t work though, so we need something a bit smarter. Instead we want the type inference algorithm of C# to help us out. Say we have a NewTheorem&amp;lt;T&amp;gt; method that takes in something of that type T, then we can call the method as follows:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font face="Courier New"&gt;ctx.NewTheorem(123)&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;without having to specify the type T explicitly as it gets inferred from the first argument. In the sample above it would be inferred to “int”. This also allows us to specify an anonymous type without stating it, like this:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font face="Courier New"&gt;ctx.NewTheorem(&lt;font color="#0000ff"&gt;new &lt;/font&gt;{ x = &lt;font color="#0000ff"&gt;default&lt;/font&gt;(&lt;font color="#0000ff"&gt;int&lt;/font&gt;), y = &lt;font color="#0000ff"&gt;default&lt;/font&gt;(&lt;font color="#0000ff"&gt;int&lt;/font&gt;) })&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Think away the default(…) parts an it almost looks like ML-style of variable declaration: x : int, y : int. This has the slight disadvantage of creating an instance of the anonymous type, just to infer its type (as you’ll see further on in this series, we won’t use the parameter value at all). If you really want to get rid of that as well, you could go for a Func&amp;lt;T&amp;gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#008080"&gt;Theorem&lt;/font&gt;&amp;lt;T&amp;gt; NewTheorem&amp;lt;T&amp;gt;(&lt;font color="#008080"&gt;Func&lt;/font&gt;&amp;lt;T&amp;gt; ctor) { … }

      &lt;br /&gt;ctx.NewTheorem(() =&amp;gt; &lt;font color="#0000ff"&gt;new &lt;/font&gt;{ x = &lt;font color="#0000ff"&gt;default&lt;/font&gt;(&lt;font color="#0000ff"&gt;int&lt;/font&gt;), y = &lt;font color="#0000ff"&gt;default&lt;/font&gt;(&lt;font color="#0000ff"&gt;int&lt;/font&gt;) });&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But that’s overkill (and yet a bit more of noise).&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Instantiating Theorem objects – Option 2&lt;/h2&gt;

&lt;p&gt;An alternative, but more complex to implement, way would be to use LINQ syntax “all the way” to establish a theorem proving environment context, using the let keyword. Instead of writing the following:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;var&lt;/font&gt; theo = &lt;font color="#0000ff"&gt;from &lt;/font&gt;t &lt;font color="#0000ff"&gt;in &lt;/font&gt;ctx.NewTheorem(&lt;font color="#0000ff"&gt;new &lt;/font&gt;{ x = &lt;font color="#0000ff"&gt;default&lt;/font&gt;(&lt;font color="#0000ff"&gt;int&lt;/font&gt;), y = &lt;font color="#0000ff"&gt;default&lt;/font&gt;(&lt;font color="#0000ff"&gt;int&lt;/font&gt;) })

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#0000ff"&gt;where&lt;/font&gt; t.x == t.y

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#0000ff"&gt;select &lt;/font&gt;t;&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;we’d now write this:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;var &lt;/font&gt;theo = &lt;font color="#0000ff"&gt;from &lt;/font&gt;t &lt;font color="#0000ff"&gt;in &lt;/font&gt;ctx.NewTheorem()

      &lt;br /&gt;&lt;font color="#0000ff"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; let &lt;/font&gt;x = t.MakeInt()

      &lt;br /&gt;&lt;font color="#0000ff"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;let &lt;/font&gt;y = t.MakeInt()

      &lt;br /&gt;&lt;font color="#0000ff"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;where &lt;/font&gt;x == y

      &lt;br /&gt;&lt;font color="#0000ff"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;select new &lt;/font&gt;{ x, y };&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the first fragment the range variable t is of type “whatever the anonymous type specified was”, hence t.x and t.y resolve to the properties declared in there. In the second fragment, t would be some “theorem constructor assistant” type that has factory methods for the supported theorem symbol types, like Int or Bool. This has several advantages:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The user is helped not to introduce types that do not make sense (although the let clauses could be used to bring other types in scope);&lt;/li&gt;

  &lt;li&gt;The where constraint clause looks very natural.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, the select part gets a little more involved if we want to extract the resulting values straight away. The main reason I’m not going for this approach right now is its complexity internally. The fragment above translates into:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font face="Courier New"&gt;var theo = ctx.NewTheorem()
      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Select(t =&amp;gt; new { t, x = t.MakeInt() })

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Select(*1 =&amp;gt; new { *1, y = *1.t.MakeInt() })

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Where(*2 =&amp;gt; *2.*1.x == *2.y)

      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Select(*2 =&amp;gt; new { x = *2.*1.x, *2.y });&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What the *1, *2, you might think. What you’re seeing here are &lt;strong&gt;transparent identifiers&lt;/strong&gt; at work (see the * notation in my &lt;a href="http://community.bartdesmet.net/blogs/bart/archive/2008/08/30/c-3-0-query-expression-translation-cheat-sheet.aspx"&gt;C# 3.0 Query Expression Translation Cheat Sheet&lt;/a&gt;). This is a very powerful feature of C# 3.0 that allows you to write seamless query comprehensions code with multiple range variables in scope, but dealing with it from a LINQ binding’s perspective gets a bit complicated. I might go there in a future post though, but for now we’ll stick with option 1.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Implementing Where&lt;/h2&gt;

&lt;p&gt;As stated earlier, we’re about to use the “where” clause as a way to specify constraints. In other words, we need a suitable Where method so that LINQ can party on it. Where does that Where method needs to live? Obviously on the return type of the NewTheorem&amp;lt;T&amp;gt; method, which – as we saw above – is a Theorem&amp;lt;T&amp;gt; on the given context object (to be specified later how the context object looks like). Calling Where should put us back in the world of Theorem&amp;lt;T&amp;gt;, so that additional constraints can be specified again.&lt;/p&gt;

&lt;p&gt;In order to distinguish the generic-driven query pattern from the underlying theorem solving implementation, we’ll have Theorem&amp;lt;T&amp;gt; derive from Theorem, where the latter will keep track of the collection of applied constraints.&lt;/p&gt;

&lt;p&gt;Now the important bit first: applying Where on a Theorem&amp;lt;T&amp;gt; should provide a new instance of a Theorem&amp;lt;T&amp;gt; instead of modifying the existing one. This is the case for all LINQ implementations as the query pattern is arbitrarily composable:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;var &lt;/font&gt;expensive = &lt;font color="#0000ff"&gt;from &lt;/font&gt;p &lt;font color="#0000ff"&gt;in &lt;/font&gt;products

      &lt;br /&gt;&lt;font color="#0000ff"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; where &lt;/font&gt;p.Price &amp;gt; 100m

      &lt;br /&gt;&lt;font color="#0000ff"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;select &lt;/font&gt;p;

      &lt;br /&gt;

      &lt;br /&gt;&lt;font color="#0000ff"&gt;var &lt;/font&gt;expensiveBeverages = &lt;font color="#0000ff"&gt;from &lt;/font&gt;p &lt;font color="#0000ff"&gt;in &lt;/font&gt;expensive

      &lt;br /&gt;&lt;font color="#0000ff"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;where &lt;/font&gt;p.Category == &lt;font color="#008080"&gt;Category&lt;/font&gt;.Beverages

      &lt;br /&gt;&lt;font color="#0000ff"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;select&lt;/font&gt; p;

      &lt;br /&gt;

      &lt;br /&gt;&lt;font color="#0000ff"&gt;var &lt;/font&gt;expensiveFruits = &lt;font color="#0000ff"&gt;from &lt;/font&gt;p &lt;font color="#0000ff"&gt;in &lt;/font&gt;expensive

      &lt;br /&gt;&lt;font color="#0000ff"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;where &lt;/font&gt;p.Category == &lt;font color="#008080"&gt;Category&lt;/font&gt;.Fruits

      &lt;br /&gt;&lt;font color="#0000ff"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#0000ff"&gt;select&lt;/font&gt; p;&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If the second query’s Where method were to mutate the “expensive” object by adding more predicates to it, the expensiveFruits query would now query over expensive beverages because expensive got mutated. This is clearly not what we want, so every application of a query operator should provide a new instance of a query object.&lt;/p&gt;

&lt;p&gt;This brings us to the implementation part. Notice I’ve weeded out any of the theorem translating code as that will be subject of the next few posts:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color:green;"&gt;Representation of a theorem with its constraints.
&lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
&lt;/span&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Theorem
&lt;/span&gt;{
    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Z3 context under which the theorem is solved.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Z3Context &lt;/span&gt;_context;

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Theorem constraints.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;LambdaExpression&lt;/span&gt;&amp;gt; _constraints;

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Creates a new theorem for the given Z3 context.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;context&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Z3 context.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;protected &lt;/span&gt;Theorem(&lt;span style="color:#2b91af;"&gt;Z3Context &lt;/span&gt;context)
        : &lt;span style="color:blue;"&gt;this&lt;/span&gt;(context, &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;LambdaExpression&lt;/span&gt;&amp;gt;())
    {
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Creates a new pre-constrained theorem for the given Z3 context.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;context&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Z3 context.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;constraints&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Constraints to apply to the created theorem.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;protected &lt;/span&gt;Theorem(&lt;span style="color:#2b91af;"&gt;Z3Context &lt;/span&gt;context, &lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;LambdaExpression&lt;/span&gt;&amp;gt; constraints)
    {
        _context = context;
        _constraints = constraints;
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Gets the Z3 context under which the theorem is solved.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;protected &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Z3Context &lt;/span&gt;Context
    {
        &lt;span style="color:blue;"&gt;get
        &lt;/span&gt;{
            &lt;span style="color:blue;"&gt;return &lt;/span&gt;_context;
        }
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Gets the constraints of the theorem.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;protected &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;LambdaExpression&lt;/span&gt;&amp;gt; Constraints
    {
        &lt;span style="color:blue;"&gt;get
        &lt;/span&gt;{
            &lt;span style="color:blue;"&gt;return &lt;/span&gt;_constraints;
        }
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Solves the theorem using Z3.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Theorem environment type.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Result of solving the theorem; default(T) if the theorem cannot be satisfied.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;protected &lt;/span&gt;T Solve&amp;lt;T&amp;gt;()
    {&lt;br /&gt;&lt;span style="color:green;"&gt;&lt;/span&gt;&lt;font color="#008000"&gt;        // To be covered in the next posts.&lt;/font&gt;&lt;br /&gt;&lt;font color="#000000"&gt;    }&lt;/font&gt;&lt;/pre&gt;

  &lt;pre class="code"&gt;    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Returns a comma-separated representation of the constraints embodied in the theorem.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Comma-separated string representation of the theorem&amp;#39;s constraints.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public override string &lt;/span&gt;ToString()
    {
        &lt;span style="color:blue;"&gt;return string&lt;/span&gt;.Join(&lt;span style="color:#a31515;"&gt;&amp;quot;, &amp;quot;&lt;/span&gt;, (&lt;span style="color:blue;"&gt;from &lt;/span&gt;c &lt;span style="color:blue;"&gt;in &lt;/span&gt;_constraints &lt;span style="color:blue;"&gt;select &lt;/span&gt;c.Body.ToString()).ToArray());
    }
}&lt;/pre&gt;
  &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;So, the non-generic Theorem type is simply a container for a set of constraints, each of which is a lambda expression, e.g. t =&amp;gt; t.x == t.y. Its generic counterpart, Theorem&amp;lt;T&amp;gt;, provides the strongly typed query pattern – just Where in our case – on top of it:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color:green;"&gt;Strongly-typed theorem type for use with LINQ syntax.
&lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;typeparam name=&amp;quot;T&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Enviroment type over which the theorem is defined.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
&lt;/span&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Theorem&lt;/span&gt;&amp;lt;T&amp;gt; : &lt;span style="color:#2b91af;"&gt;Theorem
&lt;/span&gt;{
    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Creates a new theorem for the given Z3 context.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;context&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Z3 context.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;internal &lt;/span&gt;Theorem(&lt;span style="color:#2b91af;"&gt;Z3Context &lt;/span&gt;context)
        : &lt;span style="color:blue;"&gt;base&lt;/span&gt;(context)
    {
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Creates a new pre-constrained theorem for the given Z3 context.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;context&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Z3 context.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&amp;quot;constraints&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Constraints to apply to the created theorem.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;internal &lt;/span&gt;Theorem(&lt;span style="color:#2b91af;"&gt;Z3Context &lt;/span&gt;context, &lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;LambdaExpression&lt;/span&gt;&amp;gt; constraints)
        : &lt;span style="color:blue;"&gt;base&lt;/span&gt;(context, constraints)
    {
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Where query operator, used to add constraints to the theorem.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;constraint&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Theorem constraint expression.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Theorem with the new constraint applied.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Theorem&lt;/span&gt;&amp;lt;T&amp;gt; Where(&lt;span style="color:#2b91af;"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;T, &lt;span style="color:blue;"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; constraint)
    {
        &lt;span style="color:blue;"&gt;return new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Theorem&lt;/span&gt;&amp;lt;T&amp;gt;(&lt;span style="color:blue;"&gt;base&lt;/span&gt;.Context, &lt;span style="color:blue;"&gt;base&lt;/span&gt;.Constraints.Concat(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;LambdaExpression&lt;/span&gt;&amp;gt; { constraint }));
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Solves the theorem.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Environment type instance with properties set to theorem-satisfying values.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;T Solve()
    {
        &lt;span style="color:blue;"&gt;return base&lt;/span&gt;.Solve&amp;lt;T&amp;gt;();
    }
}&lt;/pre&gt;
  &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;Notice how the Where method creates a new instance of Theorem&amp;lt;T&amp;gt;, passing in the original context as well as the concatenation of the current constraints with the new constraint.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;A look at the Z3Context type&lt;/h2&gt;

&lt;p&gt;Finally to finish up this first post, we’ll have a peek at the Z3Context type, from which everything starts by creating Theorem&amp;lt;T&amp;gt; instances out of it:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
/// &lt;/span&gt;&lt;span style="color:green;"&gt;Context object for Z3 theorem proving through LINQ. Manages the configuration
&lt;/span&gt;&lt;span style="color:gray;"&gt;/// &lt;/span&gt;&lt;span style="color:green;"&gt;of the theorem prover and provides centralized infrastructure for logging.
&lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
&lt;/span&gt;&lt;span style="color:blue;"&gt;public sealed class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Z3Context &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;IDisposable
&lt;/span&gt;{
    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Z3 configuration object.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Config &lt;/span&gt;_config;

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Creates a new Z3 context for theorem proving.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;Z3Context()
    {
        _config = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Config&lt;/span&gt;();
        _config.SetParamValue(&lt;span style="color:#a31515;"&gt;&amp;quot;MODEL&amp;quot;&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;&amp;quot;true&amp;quot;&lt;/span&gt;);
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Gets/sets the logger used for diagnostic output.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;TextWriter &lt;/span&gt;Log { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Creates a new theorem based on the given type to establish the environment with
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &lt;/span&gt;&lt;span style="color:green;"&gt;the variables constrained by the theorem.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Theorem environment type.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;New theorem object based on the given environment.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Theorem&lt;/span&gt;&amp;lt;T&amp;gt; NewTheorem&amp;lt;T&amp;gt;()
    {
        &lt;span style="color:blue;"&gt;return new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Theorem&lt;/span&gt;&amp;lt;T&amp;gt;(&lt;span style="color:blue;"&gt;this&lt;/span&gt;);
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Creates a new theorem based on a skeleton object used to infer the environment
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &lt;/span&gt;&lt;span style="color:green;"&gt;type with the variables constrained by the theorem.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// 
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;This overload is useful if one wants to use an anonymous type &amp;quot;on the fly&amp;quot; to
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &lt;/span&gt;&lt;span style="color:green;"&gt;create a new theorem based on the type&amp;#39;s properties as variables.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;example&amp;gt;
    /// &amp;lt;code&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;ctx.NewTheorem(new { x = default(int), y = default(int) }).Where(t =&amp;gt; t.x &amp;gt; t.y)
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/code&amp;gt;
    /// &amp;lt;/example&amp;gt;
    /// &amp;lt;typeparam name=&amp;quot;T&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Theorem environment type (typically inferred).&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/typeparam&amp;gt;
    /// &amp;lt;param name=&amp;quot;dummy&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Dummy parameter, typically an anonymous type instance.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;New theorem object based on the given environment.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Theorem&lt;/span&gt;&amp;lt;T&amp;gt; NewTheorem&amp;lt;T&amp;gt;(T dummy)
    {
        &lt;span style="color:blue;"&gt;return new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Theorem&lt;/span&gt;&amp;lt;T&amp;gt;(&lt;span style="color:blue;"&gt;this&lt;/span&gt;);
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Closes the native resources held by the Z3 theorem prover.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;public void &lt;/span&gt;Dispose()
    {
        _config.Dispose();
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Factory method for Z3 contexts based on the given configuration.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;New Z3 context.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/returns&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;internal &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Context &lt;/span&gt;CreateContext()
    {
        &lt;span style="color:blue;"&gt;return new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Context&lt;/span&gt;(_config);
    }

    &lt;span style="color:gray;"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/span&gt;&lt;span style="color:green;"&gt;Helpers to write diagnostic log output to the registered logger, if any.
    &lt;/span&gt;&lt;span style="color:gray;"&gt;/// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&amp;quot;s&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:green;"&gt;Log output string.&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/param&amp;gt;
    &lt;/span&gt;&lt;span style="color:blue;"&gt;internal void &lt;/span&gt;LogWriteLine(&lt;span style="color:blue;"&gt;string &lt;/span&gt;s)
    {
        &lt;span style="color:blue;"&gt;if &lt;/span&gt;(Log != &lt;span style="color:blue;"&gt;null&lt;/span&gt;)
            Log.WriteLine(s);
    }
}&lt;/pre&gt;
  &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;There’s the first little bit of Z3 coming in, with the constructor new’ing up a Z3 context object. It’s this context that will provide the entry-point to Z3 theorem solving going forward. Given all of this machinery we can already start writing code like this:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;using &lt;/span&gt;(&lt;span style="color:blue;"&gt;var &lt;/span&gt;ctx = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Z3Context&lt;/span&gt;())
{
    ctx.Log = &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.Out;

    &lt;span style="color:blue;"&gt;var &lt;/span&gt;theo = &lt;span style="color:blue;"&gt;from &lt;/span&gt;t &lt;span style="color:blue;"&gt;in &lt;/span&gt;ctx.NewTheorem(&lt;span style="color:blue;"&gt;new &lt;/span&gt;{ x = &lt;span style="color:blue;"&gt;default&lt;/span&gt;(&lt;span style="color:blue;"&gt;bool&lt;/span&gt;), y = &lt;span style="color:blue;"&gt;default&lt;/span&gt;(&lt;span style="color:blue;"&gt;bool&lt;/span&gt;) })
               &lt;span style="color:blue;"&gt;where &lt;/span&gt;t.x ^ t.y
               &lt;span style="color:blue;"&gt;select &lt;/span&gt;t;

    &lt;span style="color:blue;"&gt;var &lt;/span&gt;result = theo.Solve();
    &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(result);
}&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;Oh, and by the way, we don’t have a Select method implemented on Theorem&amp;lt;T&amp;gt;. Even though the query above has a projection specified, Select is not required as the projection is a trivial one which gets compiled away by the compiler. When and why this happens you can read in &lt;a href="http://community.bartdesmet.net/blogs/bart/archive/2008/08/20/what-do-vb-9-0-error-bc36593-expression-of-type-x-is-not-queryable-and-c-3-0-error-cs1936-could-not-find-an-implementation-of-the-query-pattern-for-source-type-x-really-mean.aspx"&gt;another blog post of mine&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Solve won’t do much yet, but that’s what we’ll be talking about next time. Oooh the suspense :-).&lt;/p&gt;&lt;img src="http://bartdesmet.net/aggbug.aspx?PostID=14410" width="1" height="1"&gt;</description><category domain="http://bartdesmet.net/blogs/bart/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://bartdesmet.net/blogs/bart/archive/tags/Crazy+Sundays/default.aspx">Crazy Sundays</category><category domain="http://bartdesmet.net/blogs/bart/archive/tags/Z3/default.aspx">Z3</category><category domain="http://bartdesmet.net/blogs/bart/archive/tags/Microsoft+Research/default.aspx">Microsoft Research</category></item><item><title>Exploring the Z3 Theorem Prover (with a bit of LINQ)</title><link>http://bartdesmet.net/blogs/bart/archive/2009/04/15/exploring-the-z3-theorem-prover-with-a-bit-of-linq.aspx</link><pubDate>Wed, 15 Apr 2009 08:33:00 GMT</pubDate><guid isPermaLink="false">863c5522-913f-4a64-ac0a-bd5f05abad0f:14391</guid><dc:creator>bart</dc:creator><slash:comments>10</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://bartdesmet.net/blogs/bart/rsscomments.aspx?PostID=14391</wfw:commentRss><comments>http://bartdesmet.net/blogs/bart/archive/2009/04/15/exploring-the-z3-theorem-prover-with-a-bit-of-linq.aspx#comments</comments><description>&lt;h1&gt;Introduction&lt;/h1&gt;
&lt;p&gt;Today I’m going to deviate from the typical path of mainstream technologies I normally cover and enter the domain of research instead. But very interesting and active research, with lots of practical implementations it turns out: &lt;strong&gt;theorem provers&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;A little story first. I guess it should have been a couple of years ago now that I first came in touch with &lt;a href="http://research.microsoft.com/en-us/um/redmond/projects/z3/"&gt;Z3&lt;/a&gt; rather accidentally when browsing the MSR website. At the time, I explored it just a little and was pretty excited about it but never go around to write about it. On &lt;a href="http://community.bartdesmet.net/blogs/bart/archive/2009/02/22/upcoming-trips-techdays-finland-belgium-and-more.aspx"&gt;my last speaker tour&lt;/a&gt; however, I met &lt;a href="http://research.microsoft.com/en-us/people/jhalleux/"&gt;Peli&lt;/a&gt;, a fellow Belgian here at Microsoft in Redmond, over at &lt;a href="http://research.microsoft.com/"&gt;Microsoft Research (MSR)&lt;/a&gt; working on the &lt;a href="http://research.microsoft.com/en-us/projects/Pex/"&gt;Pex&lt;/a&gt; project (remember me to blog about Pex and &lt;a href="http://research.microsoft.com/en-us/projects/contracts/"&gt;Code Contracts&lt;/a&gt; in .NET 4.0). Since Pex uses Z3 internally you can guess the rest of the story and how I got inspired to dig Z3 up again and write this post.&lt;/p&gt;
&lt;h1&gt;Enrich your vocab – Satisfiability Modulo Theories&lt;/h1&gt;
&lt;p&gt;So what’s Z3 about? In two words: it’s an &lt;strong&gt;SMT solver&lt;/strong&gt;. SMT stands for Satisfiability Modulo Theories, but let’s elaborate on those expensive words a bit to make things clear, going from right to left:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Theories&lt;/strong&gt; are domains within which we want to verify certain properties, ideally in an automated fashion. Z3 supports a number of built-in theories such as integer arithmetic, arrays and bit-vectors, free functions, etc. In practice those theories are mapped onto domain-specific models where theorem proving is required, e.g. what are the conditions to hit a certain code path (for test code generation as in Pex), can certain predicates be violated by a method’s execution (for &lt;a href="http://en.wikipedia.org/wiki/Hoare_logic"&gt;Hoare triples&lt;/a&gt; with pre- and post-conditions, or invariants as in Spec#), do certain properties have a possibility to be true simultaneously (indicating a bug, caught by verifying compilers like Boogie), or can a code block ever be hit (allowing dead code elimination by optimizing compilers); &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Modulo&lt;/strong&gt; is simply glue which can be read as “under the presence of certain”; &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Satisfiability&lt;/strong&gt; is where the fun comes in. We have our theories as an ingredient for an SMT solver, but with a theory alone we can’t do much. Well, we could feed in all possible inputs to build a table of potential outcomes. That’s madness because of exponential growth for table sizes in terms of the number of inputs. Even more, often we’re not interested in every single input: we rather want to know whether it’s even possible for a certain formula to hold &lt;em&gt;ever&lt;/em&gt; under the given theories. This is what satisfiability stands for, and it’s a hard problem many mathematicians have dealt with (to get a broader context search for terms like “&lt;a href="http://mathworld.wolfram.com/Entscheidungsproblem.html"&gt;Entscheidungsproblem&lt;/a&gt;”, “decidability” or for names of famous mathematicians like Hilbert, Godel, Church and Turing, Kleene and Rosser, amongst others). &lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;To illustrate this has been applied very practically, a few samples of success stories:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hyper-V, our flagship virtualization platform foundation, was built using a verifying C compiler (&lt;a href="http://research.microsoft.com/en-us/projects/vcc/"&gt;VCC&lt;/a&gt;) making it possible to catch issues with heap corruption (provability of correctness is a great deal there, to avoid discussions where guest OS’es blame the host OS for memory corruption) and such; &lt;/li&gt;
&lt;li&gt;Driver verification in Windows 7 (&lt;a href="http://www.microsoft.com/whdc/devtools/tools/SDV.mspx"&gt;SDV 2.0&lt;/a&gt;) leverages Z3; &lt;/li&gt;
&lt;li&gt;Spec# and Pex use Z3 for verification and test case generation purposes respectively – this extends to the domain of Code Contracts where static verification tools are integrated with Visual Studio to catch code contract violations early; &lt;/li&gt;
&lt;li&gt;Other domains include correctness checks for security stack implementations, cryptography algorithms, verification of garbage collectors (which are ultimately manipulators of large byte arrays) e.g. as used in &lt;a href="http://research.microsoft.com/en-us/groups/os/singularity/"&gt;Singularity&lt;/a&gt; for core OS services, program termination analysis, etc. &lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;In exciting domains as theorem solving, you can guess there are competitions too… &lt;a href="http://www.smtexec.org/exec/"&gt;SMT-COMP’08&lt;/a&gt; is one such competition, where Z3 scored very high results. &lt;/p&gt;
&lt;h1&gt;Getting started with Z3&lt;/h1&gt;
&lt;p&gt;The obvious first step towards exploring Z3 is to get your hands on the bits, which you can find &lt;a href="http://research.microsoft.com/en-us/um/redmond/projects/z3/download.html"&gt;over here&lt;/a&gt;. I’ll be using the 1.3 release of Z3 throughout this post. Please read the license that goes with Z3 as use of research technology has certain restrictions (I’m not a lawyer, so I’m not trying to paraphrase it in my own non-legalese :-)).&lt;/p&gt;
&lt;p&gt;The installation will install binaries, samples and documentation to %programfiles%\Microsoft Research\Z3-1.3.6. Two files are of particular interest to our first exploration in this post:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://bartdesmet.info/images_wlw/ExploringtheZ3TheoremProverwithabitofLIN_1A1/image.png"&gt;&lt;img style="BORDER-RIGHT-WIDTH:0px;DISPLAY:inline;BORDER-TOP-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-LEFT-WIDTH:0px;" title="image" border="0" alt="image" src="http://bartdesmet.info/images_wlw/ExploringtheZ3TheoremProverwithabitofLIN_1A1/image_thumb.png" width="640" height="280" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;z3.exe&lt;/strong&gt; is the command-line theorem prover. It can accept problem inputs in specialized formats used in the domain of SMTs. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Microsoft.Z3.dll &lt;/strong&gt;is a managed wrapper around the theorem solver, allowing any .NET language to call into Z3 as a library. &lt;/li&gt;&lt;/ul&gt;
&lt;h1&gt;Using the Z3.exe command-line tool&lt;/h1&gt;
&lt;p&gt;Before we get into doing any coding ourselves, let’s just use the built-in command-line tool first. As this is an introductory post I’ll just cover a very basic subset of the possibilities of the tool. More specifically, I’ll restrict myself to the domain of Boolean logic – you know those things with true and false, conjunctions, disjunctions and negations – and just the subset of &lt;a href="http://en.wikipedia.org/wiki/Propositional_logic"&gt;propositional logic&lt;/a&gt;. This by itself is an interesting study, but be aware that the theories Z3 can tackle are much richer than just this.&lt;/p&gt;
&lt;p&gt;Anyway, what we want to do is ask the theorem prover to try to find a set of assignments for variables that make a certain formula hold, in other words that satisfy the criterion expressed by the formula under the theory of Boolean logic. One way to express this is by using an input file in a format Z3 understands. We’ll use the &lt;a href="http://www.smtlib.org/"&gt;SMT-LIB&lt;/a&gt; format and write a file that states the problem of trying to satisfy the formula:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;a xor b&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;In other words, try to find values for a and b for which this formula evaluates to true. We can translate this into SMT-LIB format by declaring a benchmark, the domain-specific lingo for a logical formula that will be checked for satisfiability against given background theories:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font face="Courier new"&gt;(benchmark demo &lt;br /&gt;:status sat &lt;br /&gt;:logic QF_UF &lt;br /&gt;:extrapreds ((a) (b)) &lt;br /&gt;:formula (xor a b) &lt;br /&gt;)&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;This simply means we’re declaring a benchmark with name “demo” which we check for satisfiability (“sat”) using the QF_UF theory (we could use other theories here, see &lt;a href="http://combination.cs.uiowa.edu/smtlib/theories.html"&gt;theories&lt;/a&gt; for a full list, but don’t worry too much about this for now) with predicates a and b and finally specifying our formula to be checked.&lt;/p&gt;
&lt;p&gt;We save this specification to a .smt file and feed it in to z3 as shown below:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="http://bartdesmet.info/images_wlw/ExploringtheZ3TheoremProverwithabitofLIN_1A1/image_3.png"&gt;&lt;img style="BORDER-RIGHT-WIDTH:0px;DISPLAY:inline;BORDER-TOP-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-LEFT-WIDTH:0px;" title="image" border="0" alt="image" src="http://bartdesmet.info/images_wlw/ExploringtheZ3TheoremProverwithabitofLIN_1A1/image_thumb_3.png" width="681" height="346" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Here the /m command-line flag means to display a model, i.e. a set of inputs satisfying our formula, allowing us to check the result. Alternatively we could omit the /m flag in which case z3 will just print “sat” to signal it has been able to prove the formula. In the run above we chose to display the model and found a solution where a is chosen to be true and b chosen to be false.&lt;/p&gt;
&lt;p&gt;Exercise for the reader: test a tautology (like a or not a) and a contradiction (like a and not a) and see what happens. Try changing the :status to unsat and see what happens.&lt;/p&gt;
&lt;h1&gt;Say it with code&lt;/h1&gt;
&lt;p&gt;Z3 can also be used as a library either from native or managed code. For the purpose of this post, we’ll explore the managed code route. In a simple C# console application project, add a reference to the Microsoft.Z3.dll file in the location we’ve shown earlier. Next, import the Microsoft.Z3 namespace. With this set up, we’re ready to write code targeting Z3. Below is the simplest possible sample:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt; System; &lt;br /&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt; Microsoft.Z3; &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;namespace &lt;/font&gt;Z3Demo &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;class &lt;/font&gt;&lt;font color="#008080"&gt;Program&lt;/font&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;static void &lt;/font&gt;Main() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;using &lt;/font&gt;(&lt;font color="#008080"&gt;Config &lt;/font&gt;config = &lt;font color="#0000ff"&gt;new &lt;/font&gt;&lt;font color="#008080"&gt;Config&lt;/font&gt;()) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; config.SetParamValue(&lt;font color="#800000"&gt;&amp;quot;MODEL&amp;quot;&lt;/font&gt;, &lt;font color="#800000"&gt;&amp;quot;true&amp;quot;&lt;/font&gt;); &lt;font color="#008000"&gt;// corresponds to /m switch &lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;using &lt;/font&gt;(&lt;font color="#008080"&gt;Context &lt;/font&gt;context = &lt;font color="#0000ff"&gt;new &lt;/font&gt;&lt;font color="#008080"&gt;Context&lt;/font&gt;(config)) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#008080"&gt;IntPtr &lt;/font&gt;a = context.MkConst(&lt;font color="#800000"&gt;&amp;quot;a&amp;quot;&lt;/font&gt;, context.MkBoolType()); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#008080"&gt;IntPtr &lt;/font&gt;b = context.MkConst(&lt;font color="#800000"&gt;&amp;quot;b&amp;quot;&lt;/font&gt;, context.MkBoolType()); &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#008080"&gt;IntPtr &lt;/font&gt;xor = context.MkXor(a, b); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; context.AssertCnstr(xor); &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#008080"&gt;Console&lt;/font&gt;.WriteLine(context.ToString(xor)); &lt;font color="#008000"&gt;// (xor a b) &lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#008080"&gt;Model &lt;/font&gt;model = &lt;font color="#0000ff"&gt;null&lt;/font&gt;; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#008080"&gt;LBool &lt;/font&gt;result = context.CheckAndGetModel(&lt;font color="#0000ff"&gt;ref &lt;/font&gt;model); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#008080"&gt;Console&lt;/font&gt;.WriteLine(result); &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;if &lt;/font&gt;(model != &lt;font color="#0000ff"&gt;null&lt;/font&gt;) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;using &lt;/font&gt;(model) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;bool &lt;/font&gt;aVal = model.GetBoolValueBool(model.Eval(a)); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;bool &lt;/font&gt;bVal = model.GetBoolValueBool(model.Eval(b)); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#008080"&gt;Console&lt;/font&gt;.WriteLine(&lt;font color="#800000"&gt;&amp;quot;a = {0}, b = {1}&amp;quot;&lt;/font&gt;, aVal, bVal); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Notice this API reflects the nature of the unmanaged (well, native) beast underneath it; the result of creating objects through the context is handle-based, hence the IntPtr use everywhere. The flow should be pretty clear: once we have the context, we build up our formula expression to be checked. Next, we assert the created constraint to the context: this allows multiple constraints to be solved together (something we’re not doing yet in this sample). Finally we check the constraints and get a model back, assuming the result says “True” meaning satisfiability has been proven.&lt;/p&gt;
&lt;p&gt;Executing this prints the following:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="http://bartdesmet.info/images_wlw/ExploringtheZ3TheoremProverwithabitofLIN_1A1/image_4.png"&gt;&lt;img style="BORDER-RIGHT-WIDTH:0px;DISPLAY:inline;BORDER-TOP-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-LEFT-WIDTH:0px;" title="image" border="0" alt="image" src="http://bartdesmet.info/images_wlw/ExploringtheZ3TheoremProverwithabitofLIN_1A1/image_thumb_4.png" width="681" height="241" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Just as we expected, didn’t we?&lt;/p&gt;
&lt;p&gt;Note for 64-bit users. Z3 relies on the VC runtime and has unmanaged code that requires to run as a 32-bit process. Just compiling your code as an IL-only assembly will cause the resulting executable to fail loading on a 64-bit machine as the CLR will JIT compile it into 64-bit at runtime. To fix this, either compile the assembly using the /platform:x86 flag (available in Visual Studio through the project properties) or run corflags.exe on the build output to force it as a 32-bit process:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="http://bartdesmet.info/images_wlw/ExploringtheZ3TheoremProverwithabitofLIN_1A1/image_5.png"&gt;&lt;img style="BORDER-RIGHT-WIDTH:0px;DISPLAY:inline;BORDER-TOP-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-LEFT-WIDTH:0px;" title="image" border="0" alt="image" src="http://bartdesmet.info/images_wlw/ExploringtheZ3TheoremProverwithabitofLIN_1A1/image_thumb_5.png" width="681" height="550" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Exercise to the reader: try out a few other propositions, possibly with more variables.&lt;/p&gt;
&lt;h1&gt;LINQ, you say?&lt;/h1&gt;
&lt;p&gt;Did see the forest through the (expression) trees? What we just did was declaring an Boolean-typed expression tree:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;var &lt;/font&gt;&lt;/font&gt;a = context.MkConst(&lt;font color="#800000"&gt;&amp;quot;a&amp;quot;&lt;/font&gt;, context.MkBoolType()); &lt;br /&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;var &lt;/font&gt;&lt;/font&gt;b = context.MkConst(&lt;font color="#800000"&gt;&amp;quot;b&amp;quot;&lt;/font&gt;, context.MkBoolType()); &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;var &lt;/font&gt;xor = context.MkXor(a, b);&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Sounds familiar? True, LINQ expression trees have similar capabilities. Simply replace context by Expression, MkConst by Parameter, MkBoolType by typeof(bool) and MkXor by ExclusiveOr and you end up with a LINQ expression tree:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;var &lt;/font&gt;&lt;/font&gt;a = &lt;font color="#008080"&gt;Expression&lt;/font&gt;.Parameter(&lt;font color="#0000ff"&gt;typeof&lt;/font&gt;(&lt;font color="#0000ff"&gt;bool&lt;/font&gt;), &lt;font color="#800000"&gt;&amp;quot;a&amp;quot;&lt;/font&gt;); &lt;br /&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;var &lt;/font&gt;&lt;/font&gt;b = &lt;font color="#008080"&gt;Expression&lt;/font&gt;.Parameter(&lt;font color="#0000ff"&gt;typeof&lt;/font&gt;(&lt;font color="#0000ff"&gt;bool&lt;/font&gt;), &lt;font color="#800000"&gt;&amp;quot;b&amp;quot;&lt;/font&gt;); &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;var &lt;/font&gt;xor = &lt;font color="#008080"&gt;Expression&lt;/font&gt;.ExclusiveOr(a, b);&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Of course, this only works because we’re using a fairly trivial subset of operations Z3 supports (more about that another time), but for Boolean propositions we could go with LINQ expression trees. Wouldn’t it be nice if we could write something like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;static void &lt;/font&gt;Main() &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Solve((a, b) =&amp;gt; a &amp;amp;&amp;amp; b); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Solve((a, b) =&amp;gt; !(a &amp;amp;&amp;amp; b)); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Solve((a, b) =&amp;gt; a || b); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Solve((a, b) =&amp;gt; !(a || b)); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Solve((a, b) =&amp;gt; a ^ b); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Solve((a, b) =&amp;gt; !(a ^ b)); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Solve(a =&amp;gt; a &amp;amp;&amp;amp; !a); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Solve(a =&amp;gt; a || !a); &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;and have it print the parameter values for which the lambda bodies evaluate to true? Guess what, let’s give it a try now. First we’ll add a couple of convenience overloads. As lambda expressions by themselves do not have a type (can either be delegates or expression trees representations thereof), it’d be quite tedious to have to write the full type name (Expression&amp;lt;Func&amp;lt;…&amp;gt;&amp;gt;) every time we want to solve for a particular lambda expression. So, a few overloads will help significantly:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;private static void &lt;/font&gt;Solve(&lt;font color="#008080"&gt;Expression&lt;/font&gt;&amp;lt;&lt;font color="#008080"&gt;Func&lt;/font&gt;&amp;lt;&lt;font color="#0000ff"&gt;bool&lt;/font&gt;, &lt;font color="#0000ff"&gt;bool&lt;/font&gt;, &lt;font color="#0000ff"&gt;bool&lt;/font&gt;&amp;gt;&amp;gt; ex) &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SolveCore(ex); &lt;br /&gt;} &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;private static void &lt;/font&gt;Solve(&lt;font color="#008080"&gt;Expression&lt;/font&gt;&amp;lt;&lt;font color="#008080"&gt;Func&lt;/font&gt;&amp;lt;&lt;font color="#0000ff"&gt;bool&lt;/font&gt;, &lt;font color="#0000ff"&gt;bool&lt;/font&gt;&amp;gt;&amp;gt; ex) &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SolveCore(ex); &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;This just calls into a SolveCore method that takes in the expression tree as a LambdaExpression object, so we can treat propositions with any number of “arguments” in exactly the same way. What we do inside this method is as follows:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;private static void&lt;/font&gt; SolveCore(&lt;font color="#008080"&gt;LambdaExpression&lt;/font&gt; f) &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#008080"&gt;Console&lt;/font&gt;.WriteLine(f); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#008080"&gt;Dictionary&lt;/font&gt;&amp;lt;&lt;font color="#008080"&gt;ParameterExpression&lt;/font&gt;, &lt;font color="#0000ff"&gt;bool&lt;/font&gt;&amp;gt; solution; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;if &lt;/font&gt;(&lt;font color="#0000ff"&gt;new &lt;/font&gt;&lt;font color="#008080"&gt;LogicConstraintSolver&lt;/font&gt;(f).Solve(&lt;font color="#0000ff"&gt;out &lt;/font&gt;solution)) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;foreach &lt;/font&gt;(&lt;font color="#0000ff"&gt;var &lt;/font&gt;parameter &lt;font color="#0000ff"&gt;in &lt;/font&gt;solution.Keys) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#008080"&gt;Console&lt;/font&gt;.WriteLine(parameter.Name + &lt;font color="#800000"&gt;&amp;quot; = &amp;quot;&lt;/font&gt; + solution[parameter]); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;else&lt;/font&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#008080"&gt;Console&lt;/font&gt;.WriteLine(&lt;font color="#800000"&gt;&amp;quot;No solution.&amp;quot;&lt;/font&gt;); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#008080"&gt;Console&lt;/font&gt;.WriteLine(); &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;The goal of this code is simple: given the lambda expression representing the proposition, go ahead and solve it, returning mappings from the parameters of the lambda expression (a, b, etc) onto the satisfying Boolean values.&lt;/p&gt;
&lt;p&gt;What does the LogicConstraintSolver look like? Essentially a visitor over the expression tree that was fed in, making sure we don’t don anything but elementary Boolean logic, and cross-compiling the expression tree into calls on a Z3 Context object.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt; &lt;font color="#008080"&gt;LogicConstraintSolver&lt;/font&gt; &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;private &lt;/font&gt;&lt;font color="#008080"&gt;LambdaExpression &lt;/font&gt;_ex; &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;public &lt;/font&gt;LogicConstraintSolver(&lt;font color="#008080"&gt;LambdaExpression &lt;/font&gt;ex) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _ex = ex; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Oh well, made nothing static for some reason. Just a proof of concept after all, and ideally you’d grab some stock visitor base type to derive from requiring instance members anyway. The next method is more interesting, I promise:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font face="Courier new"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;public bool &lt;/font&gt;Solve(&lt;font color="#0000ff"&gt;out &lt;/font&gt;&lt;font color="#008080"&gt;Dictionary&lt;/font&gt;&amp;lt;&lt;font color="#008080"&gt;ParameterExpression&lt;/font&gt;, &lt;font color="#0000ff"&gt;bool&lt;/font&gt;&amp;gt; solution) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; solution = &lt;font color="#0000ff"&gt;null&lt;/font&gt;; &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier new"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;using &lt;/font&gt;(&lt;font color="#008080"&gt;Config &lt;/font&gt;config = &lt;font color="#0000ff"&gt;new &lt;/font&gt;&lt;font color="#008080"&gt;Config&lt;/font&gt;()) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; config.SetParamValue(&lt;font color="#800000"&gt;&amp;quot;MODEL&amp;quot;&lt;/font&gt;, &lt;font color="#800000"&gt;&amp;quot;true&amp;quot;&lt;/font&gt;); &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier new"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;using &lt;/font&gt;(&lt;font color="#008080"&gt;Context &lt;/font&gt;context = &lt;font color="#0000ff"&gt;new &lt;/font&gt;&lt;font color="#008080"&gt;Context&lt;/font&gt;(config)) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;var&lt;/font&gt; environment = GetEnvironment(context); &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier new"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#008080"&gt;IntPtr &lt;/font&gt;constraint = Visit(context, environment, _ex.Body); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; context.AssertCnstr(constraint); &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier new"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#008080"&gt;Model&lt;/font&gt; model = &lt;font color="#0000ff"&gt;null&lt;/font&gt;; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#008080"&gt;LBool &lt;/font&gt;result = context.CheckAndGetModel(&lt;font color="#0000ff"&gt;ref &lt;/font&gt;model); &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier new"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;if &lt;/font&gt;(model != &lt;font color="#0000ff"&gt;null&lt;/font&gt;) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;using &lt;/font&gt;(model) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; solution = GetSolution(model, environment); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier new"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;return &lt;/font&gt;result == &lt;font color="#008080"&gt;LBool&lt;/font&gt;.True; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Macroscopically the same as our original hard-coded XOR implementation, but with the core replaced:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;First we get the environment, which will be a dictionary of ParameterExpression to IntPtr (sorry for the over-use of “var” in this sample). This maps the lambda parameters on the handles for the corresponding Z3 “constants” (returned from MkConst calls). &lt;/li&gt;
&lt;li&gt;A visitor method walks the expression tree recursively, turning it into a handle to the Z3 representation of the proposition being cross-compiled. To do so, we need the context (for use of its factory methods) and the environment from above. &lt;/li&gt;
&lt;li&gt;Finally we add the constraint, check the model, and get a solution which is again a dictionary but this time mapping the lambda parameters onto their corresponding truth values required to satisfy the proposition. &lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;Now, let’s investigate each of those helper methods. They’re fairly trivial in fact:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font face="Courier new"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;private &lt;/font&gt;&lt;font color="#008080"&gt;Dictionary&lt;/font&gt;&amp;lt;&lt;font color="#008080"&gt;ParameterExpression&lt;/font&gt;, &lt;font color="#008080"&gt;IntPtr&lt;/font&gt;&amp;gt; GetEnvironment(&lt;font color="#008080"&gt;Context &lt;/font&gt;context) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;var &lt;/font&gt;environment = &lt;font color="#0000ff"&gt;new &lt;/font&gt;&lt;font color="#008080"&gt;Dictionary&lt;/font&gt;&amp;lt;&lt;font color="#008080"&gt;ParameterExpression&lt;/font&gt;, &lt;font color="#008080"&gt;IntPtr&lt;/font&gt;&amp;gt;(); &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier new"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;foreach &lt;/font&gt;(&lt;font color="#0000ff"&gt;var &lt;/font&gt;parameter &lt;font color="#0000ff"&gt;in &lt;/font&gt;_ex.Parameters) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;if &lt;/font&gt;(parameter.Type != &lt;font color="#0000ff"&gt;typeof&lt;/font&gt;(&lt;font color="#0000ff"&gt;bool&lt;/font&gt;)) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;throw new &lt;/font&gt;&lt;font color="#008080"&gt;NotSupportedException&lt;/font&gt;(&lt;font color="#800000"&gt;&amp;quot;Non-Boolean parameter.&amp;quot;&lt;/font&gt;); &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier new"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; environment.Add(parameter, context.MkConst(parameter.Name, context.MkBoolType())); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier new"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;return &lt;/font&gt;environment; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;No magic here; just enforcing every parameter to be Boolean-typed and calling into the context to construct constants with a Bool type, ultimately storing those in a mapping table. Next is our visitor.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font face="courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;private&lt;/font&gt; &lt;font color="#008080"&gt;IntPtr &lt;/font&gt;Visit(&lt;font color="#008080"&gt;Context &lt;/font&gt;context, &lt;font color="#008080"&gt;Dictionary&lt;/font&gt;&amp;lt;&lt;font color="#008080"&gt;ParameterExpression&lt;/font&gt;, &lt;font color="#008080"&gt;IntPtr&lt;/font&gt;&amp;gt; environment, &lt;font color="#008080"&gt;Expression &lt;/font&gt;expression) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;switch &lt;/font&gt;(expression.NodeType) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;case &lt;/font&gt;&lt;font color="#008080"&gt;ExpressionType&lt;/font&gt;.And: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;case &lt;/font&gt;&lt;font color="#008080"&gt;ExpressionType&lt;/font&gt;.AndAlso: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;return &lt;/font&gt;VisitBinary(context, environment, (&lt;font color="#008080"&gt;BinaryExpression&lt;/font&gt;)expression, (ctx, a, b) =&amp;gt; ctx.MkAnd(a, b)); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;case &lt;/font&gt;&lt;font color="#008080"&gt;ExpressionType&lt;/font&gt;.Or: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;case &lt;/font&gt;&lt;font color="#008080"&gt;ExpressionType&lt;/font&gt;.OrElse: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;return &lt;/font&gt;VisitBinary(context, environment, (&lt;font color="#008080"&gt;BinaryExpression&lt;/font&gt;)expression, (ctx, a, b) =&amp;gt; ctx.MkOr(a, b)); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;case &lt;/font&gt;&lt;font color="#008080"&gt;ExpressionType&lt;/font&gt;.ExclusiveOr: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;return &lt;/font&gt;VisitBinary(context, environment, (&lt;font color="#008080"&gt;BinaryExpression&lt;/font&gt;)expression, (ctx, a, b) =&amp;gt; ctx.MkXor(a, b)); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;case &lt;/font&gt;&lt;font color="#008080"&gt;ExpressionType&lt;/font&gt;.Not: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;return &lt;/font&gt;VisitUnary(context, environment, (&lt;font color="#008080"&gt;UnaryExpression&lt;/font&gt;)expression, (ctx, a) =&amp;gt; ctx.MkNot(a)); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;case &lt;/font&gt;&lt;font color="#008080"&gt;ExpressionType&lt;/font&gt;.Parameter: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;return &lt;/font&gt;VisitParameter(context, environment, (&lt;font color="#008080"&gt;ParameterExpression&lt;/font&gt;)expression); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;default&lt;/font&gt;: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;throw new &lt;/font&gt;&lt;font color="#008080"&gt;NotSupportedException&lt;/font&gt;(&lt;font color="#800000"&gt;&amp;quot;Invalid logic expression.&amp;quot;&lt;/font&gt;); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Here we’re a bit functionally inspired. We just generalize the binary and unary cases, passing in a little lambda that given a context and the arguments can invoke the right factory method on the context object. Of course those arguments need to be filled in with concrete values, which is what the VisitBinary and VisitUnary methods are responsible for, based on recursion:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;private&lt;/font&gt; &lt;font color="#008080"&gt;IntPtr&lt;/font&gt; VisitBinary(&lt;font color="#008080"&gt;Context &lt;/font&gt;context, &lt;font color="#008080"&gt;Dictionary&lt;/font&gt;&amp;lt;&lt;font color="#008080"&gt;ParameterExpression&lt;/font&gt;, &lt;font color="#008080"&gt;IntPtr&lt;/font&gt;&amp;gt; environment, &lt;font color="#008080"&gt;BinaryExpression &lt;/font&gt;expression, &lt;font color="#008080"&gt;Func&lt;/font&gt;&amp;lt;&lt;font color="#008080"&gt;Context&lt;/font&gt;, &lt;font color="#008080"&gt;IntPtr&lt;/font&gt;, &lt;font color="#008080"&gt;IntPtr&lt;/font&gt;, &lt;font color="#008080"&gt;IntPtr&lt;/font&gt;&amp;gt; ctor) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;return &lt;/font&gt;ctor(context, Visit(context, environment, expression.Left), Visit(context, environment, expression.Right)); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;private&lt;/font&gt; &lt;font color="#008080"&gt;IntPtr&lt;/font&gt; VisitUnary(&lt;font color="#008080"&gt;Context &lt;/font&gt;context, &lt;font color="#008080"&gt;Dictionary&lt;/font&gt;&amp;lt;&lt;font color="#008080"&gt;ParameterExpression&lt;/font&gt;, &lt;font color="#008080"&gt;IntPtr&lt;/font&gt;&amp;gt; environment, &lt;font color="#008080"&gt;UnaryExpression &lt;/font&gt;expression, &lt;font color="#008080"&gt;Func&lt;/font&gt;&amp;lt;&lt;font color="#008080"&gt;Context&lt;/font&gt;, &lt;font color="#008080"&gt;IntPtr&lt;/font&gt;, &lt;font color="#008080"&gt;IntPtr&lt;/font&gt;&amp;gt; ctor) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;return &lt;/font&gt;ctor(context, Visit(context, environment, expression.Operand)); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;private&lt;/font&gt; &lt;font color="#008080"&gt;IntPtr&lt;/font&gt; VisitParameter(&lt;font color="#008080"&gt;Context &lt;/font&gt;context, &lt;font color="#008080"&gt;Dictionary&lt;/font&gt;&amp;lt;&lt;font color="#008080"&gt;ParameterExpression&lt;/font&gt;, &lt;font color="#008080"&gt;IntPtr&lt;/font&gt;&amp;gt; environment, &lt;font color="#008080"&gt;ParameterExpression&lt;/font&gt; parameter) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#008080"&gt;IntPtr&lt;/font&gt; value; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;if &lt;/font&gt;(!environment.TryGetValue(parameter, &lt;font color="#0000ff"&gt;out &lt;/font&gt;value)) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;throw new &lt;/font&gt;&lt;font color="#008080"&gt;NotSupportedException&lt;/font&gt;(&lt;font color="#800000"&gt;&amp;quot;Unknown parameter encountered: &amp;quot;&lt;/font&gt; + parameter.Name + &lt;font color="#800000"&gt;&amp;quot;.&amp;quot;&lt;/font&gt;); &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;return &lt;/font&gt;value; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;All we’re doing here is basic recursion and object construction through our passed in delegates: e.g. an AndAlso node in the LINQ expression tree has a Left and Right property. Recursively we translate those into IntPtr handles into the Z3 “object model”. Given those values, the lambda “(ctx, a, b) =&amp;gt; ctx.MkAnd(a, b)” invokes the MkAnd factory method to produce an And node in the target “object model”. The case of visiting a parameter expression simply looks up the handle to the Z3 Const node (created in GetEnvironment before) and returns it.&lt;/p&gt;
&lt;p&gt;Finally, we can get the solution from the generated model by getting the truth values for each parameter that occurs in the environment:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;private&lt;/font&gt; &lt;font color="#008080"&gt;Dictionary&lt;/font&gt;&amp;lt;&lt;font color="#008080"&gt;ParameterExpression&lt;/font&gt;, &lt;font color="#0000ff"&gt;bool&lt;/font&gt;&amp;gt; GetSolution(&lt;font color="#008080"&gt;Model &lt;/font&gt;model, &lt;font color="#008080"&gt;Dictionary&lt;/font&gt;&amp;lt;&lt;font color="#008080"&gt;ParameterExpression&lt;/font&gt;, &lt;font color="#008080"&gt;IntPtr&lt;/font&gt;&amp;gt; environment) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;var &lt;/font&gt;result = &lt;font color="#0000ff"&gt;new &lt;/font&gt;&lt;font color="#008080"&gt;Dictionary&lt;/font&gt;&amp;lt;&lt;font color="#008080"&gt;ParameterExpression&lt;/font&gt;, &lt;font color="#0000ff"&gt;bool&lt;/font&gt;&amp;gt;(); &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;foreach &lt;/font&gt;(&lt;font color="#0000ff"&gt;var &lt;/font&gt;key &lt;font color="#0000ff"&gt;in &lt;/font&gt;environment.Keys) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; result[key] = model.GetBoolValueBool(model.Eval(environment[key])); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;return &lt;/font&gt;result; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;That’s it. Barely 100 lines of code in total. And sure enough, It Just Works (TM):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="http://bartdesmet.info/images_wlw/ExploringtheZ3TheoremProverwithabitofLIN_1A1/image_6.png"&gt;&lt;img style="BORDER-RIGHT-WIDTH:0px;DISPLAY:inline;BORDER-TOP-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-LEFT-WIDTH:0px;" title="image" border="0" alt="image" src="http://bartdesmet.info/images_wlw/ExploringtheZ3TheoremProverwithabitofLIN_1A1/image_thumb_6.png" width="681" height="466" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Truly fascinating, isn’t it? But this is just the tip of the iceberg. Some next time, we’ll look at the domain of integer arithmetic to make things a bit more interesting...&lt;/p&gt;
&lt;p&gt;Exercise to the reader, in the meantime: feed the output of the theorem prover back in to the original LINQ expression to check the correctness of the answer. Use either interpretation (by visiting the expression tree) or compilation (if you feel lame and prefer a simple .Compile() call somewhere).&lt;/p&gt;
&lt;p&gt;Happy theorem proving!&lt;/p&gt;&lt;img src="http://bartdesmet.net/aggbug.aspx?PostID=14391" width="1" height="1"&gt;</description><category domain="http://bartdesmet.net/blogs/bart/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://bartdesmet.net/blogs/bart/archive/tags/Z3/default.aspx">Z3</category><category domain="http://bartdesmet.net/blogs/bart/archive/tags/Microsoft+Research/default.aspx">Microsoft Research</category></item></channel></rss>