// File: ArashPartow[P]exprtk-extras/exprtk_riddle.cpp
// Function: void logical_deducation_riddle<double>()
void logical_deducation_riddle()
{
   typedef exprtk::symbol_table<T>         symbol_table_t;
   typedef exprtk::expression<T>           expression_t;
   typedef exprtk::parser<T>               parser_t;
   typedef exprtk::function_compositor<T>  compositor_t;
   typedef typename compositor_t::function function_t;

   symbol_table_t symbol_table;

   exprtk::rtl::io::println<T> println;

   symbol_table.add_function("println", println);

   compositor_t compositor(symbol_table);

   compositor.add(function_t()
      .name("constraint")
      .var("person_x").var("person_y")
      .expression
      (
         " person_x xor person_y; "
      ));

   const std::string logical_deducation_riddle_program =
      " const var number_of_culprits := 1;                                             "
      "                                                                                "
      " for (var Tori := false; Tori <= true; Tori += true)                            "
      " {                                                                              "
      "    for (var Annie := false; Annie <= true; Annie += true)                      "
      "    {                                                                           "
      "       for (var Betsy := false; Betsy <= true; Betsy += true)                   "
      "       {                                                                        "
      "          for (var Chloe := false; Chloe <= true; Chloe += true)                "
      "          {                                                                     "
      "             for (var Zoey := false; Zoey <= true; Zoey += true)                "
      "             {                                                                  "
      "                if (sum(Annie, Betsy, Chloe, Tori, Zoey) != number_of_culprits) "
      "                   continue;                                                    "
      "                                                                                "
      "                var solution :=                                                 "
      "                   constraint( not(Zoey)  , Annie     ) and /* Tori  */         "
      "                   constraint( not(Betsy) , not(Zoey) ) and /* Annie */         "
      "                   constraint( Zoey       , not(Tori) ) and /* Betsy */         "
      "                   constraint( Betsy      , Annie     ) and /* Chloe */         "
      "                   constraint( Chloe      , not(Tori) ) ;   /* Zoey  */         "
      "                                                                                "
      "                if (solution == true)                                           "
      "                {                                                               "
      "                   var culprit := '';                                           "
      "                   [*]                                                          "
      "                   {                                                            "
      "                      case Annie : culprit := 'Annie';                          "
      "                      case Betsy : culprit := 'Betsy';                          "
      "                      case Chloe : culprit := 'Chloe';                          "
      "                      case Tori  : culprit := 'Tori' ;                          "
      "                      case Zoey  : culprit := 'Zoey' ;                          "
      "                   };                                                           "
      "                                                                                "
      "                   println(culprit,' broke the window!');                       "
      "                }                                                               "
      "             }                                                                  "
      "          }                                                                     "
      "       }                                                                        "
      "    }                                                                           "
      " }                                                                              "
      "                                                                                ";

   expression_t expression;
   expression.register_symbol_table(symbol_table);

   parser_t parser;
   parser.compile(logical_deducation_riddle_program,expression);

   expression.value();
}

// Assembly:
subq $0x1708, %rsp           # imm = 0x1708
leaq 0x1700(%rsp), %rdi
movl $0x1, %esi
callq 0x11c170
leaq 0x1677(%rsp), %rdi
movq %rdi, 0x58(%rsp)
callq 0x114660
movq 0x58(%rsp), %rdx
leaq 0x347cfe(%rip), %rsi    # 0x463565
leaq 0x1678(%rsp), %rdi
callq 0x11b770
jmp 0x11b876
leaq 0x1698(%rsp), %rdi
leaq 0x1678(%rsp), %rsi
callq 0x11c1b0
jmp 0x11b88d
leaq 0x1678(%rsp), %rdi
callq 0x1147a8
leaq 0x1677(%rsp), %rdi
callq 0x114790
leaq 0x163f(%rsp), %rdi
movq %rdi, 0x50(%rsp)
callq 0x114660
movq 0x50(%rsp), %rdx
leaq 0x347ca7(%rip), %rsi    # 0x46356c
leaq 0x1640(%rsp), %rdi
callq 0x11b770
jmp 0x11b8d4
leaq 0x1700(%rsp), %rdi
leaq 0x1640(%rsp), %rsi
leaq 0x1698(%rsp), %rdx
callq 0x11c2c0
jmp 0x11b8f3
leaq 0x1640(%rsp), %rdi
callq 0x1147a8
leaq 0x163f(%rsp), %rdi
callq 0x114790
leaq 0xc50(%rsp), %rdi
leaq 0x1700(%rsp), %rsi
callq 0x11c4c0
jmp 0x11b924
leaq 0xbc0(%rsp), %rdi
callq 0x11c6b0
jmp 0x11b933
leaq 0xb9f(%rsp), %rdi
movq %rdi, 0x48(%rsp)
callq 0x114660
movq 0x48(%rsp), %rdx
leaq 0x347c23(%rip), %rsi    # 0x463574
leaq 0xba0(%rsp), %rdi
callq 0x11b770
jmp 0x11b960
leaq 0xbc0(%rsp), %rdi
leaq 0xba0(%rsp), %rsi
callq 0x11c720
movq %rax, 0x40(%rsp)
jmp 0x11b97c
leaq 0xb77(%rsp), %rdi
movq %rdi, 0x38(%rsp)
callq 0x114660
movq 0x38(%rsp), %rdx
leaq 0x347be5(%rip), %rsi    # 0x46357f
leaq 0xb78(%rsp), %rdi
callq 0x11b770
jmp 0x11b9a9
movq 0x40(%rsp), %rdi
leaq 0xb78(%rsp), %rsi
callq 0x11c750
movq %rax, 0x30(%rsp)
jmp 0x11b9c2
leaq 0xb4f(%rsp), %rdi
movq %rdi, 0x28(%rsp)
callq 0x114660
movq 0x28(%rsp), %rdx
leaq 0x347ba8(%rip), %rsi    # 0x463588
leaq 0xb50(%rsp), %rdi
callq 0x11b770
jmp 0x11b9ef
movq 0x30(%rsp), %rdi
leaq 0xb50(%rsp), %rsi
callq 0x11c750
movq %rax, 0x20(%rsp)
jmp 0x11ba08
leaq 0xb27(%rsp), %rdi
movq %rdi, 0x18(%rsp)
callq 0x114660
movq 0x18(%rsp), %rdx
leaq 0x347b6b(%rip), %rsi    # 0x463591
leaq 0xb28(%rsp), %rdi
callq 0x11b770
jmp 0x11ba35
movq 0x20(%rsp), %rdi
leaq 0xb28(%rsp), %rsi
callq 0x11c780
movq %rax, 0x10(%rsp)
jmp 0x11ba4e
movq 0x10(%rsp), %rsi
leaq 0xc50(%rsp), %rdi
xorl %edx, %edx
callq 0x11c660
jmp 0x11ba64
leaq 0xb28(%rsp), %rdi
callq 0x1147a8
leaq 0xb27(%rsp), %rdi
callq 0x114790
leaq 0xb50(%rsp), %rdi
callq 0x1147a8
leaq 0xb4f(%rsp), %rdi
callq 0x114790
leaq 0xb78(%rsp), %rdi
callq 0x1147a8
leaq 0xb77(%rsp), %rdi
callq 0x114790
leaq 0xba0(%rsp), %rdi
callq 0x1147a8
leaq 0xb9f(%rsp), %rdi
callq 0x114790
leaq 0xbc0(%rsp), %rdi
callq 0x11c7b0
leaq 0xaff(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0x114660
movq 0x8(%rsp), %rdx
leaq 0x347ab3(%rip), %rsi    # 0x4635aa
leaq 0xb00(%rsp), %rdi
callq 0x11b770
jmp 0x11bb06
leaq 0xaff(%rsp), %rdi
callq 0x114790
leaq 0xad8(%rsp), %rdi
callq 0x11c7f0
jmp 0x11bb22
leaq 0xad8(%rsp), %rdi
leaq 0x1700(%rsp), %rsi
callq 0x11c8a0
jmp 0x11bb39
leaq 0x60(%rsp), %rdi
movl $0x7f, %esi
callq 0x11c950
jmp 0x11bb4a
leaq 0x1b0(%rsp), %rdi
leaq 0x60(%rsp), %rsi
callq 0x11ca80
jmp 0x11bb5e
leaq 0x60(%rsp), %rdi
callq 0x11d2b0
leaq 0x1b0(%rsp), %rdi
leaq 0xb00(%rsp), %rsi
leaq 0xad8(%rsp), %rdx
callq 0x11d320
jmp 0x11bb87
leaq 0xad8(%rsp), %rdi
callq 0x11dbb0
jmp 0x11bb96
leaq 0x1b0(%rsp), %rdi
callq 0x11dbd0
leaq 0xad8(%rsp), %rdi
callq 0x11ddd0
leaq 0xb00(%rsp), %rdi
callq 0x1147a8
leaq 0xc50(%rsp), %rdi
callq 0x11de10
leaq 0x1698(%rsp), %rdi
callq 0x11dea0
leaq 0x1700(%rsp), %rdi
callq 0x11ded0
addq $0x1708, %rsp           # imm = 0x1708
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1668(%rsp)
movl %eax, 0x1664(%rsp)
jmp 0x11bc23
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1668(%rsp)
movl %eax, 0x1664(%rsp)
leaq 0x1678(%rsp), %rdi
callq 0x1147a8
leaq 0x1677(%rsp), %rdi
callq 0x114790
jmp 0x11beab
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1668(%rsp)
movl %eax, 0x1664(%rsp)
jmp 0x11bc6c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1668(%rsp)
movl %eax, 0x1664(%rsp)
leaq 0x1640(%rsp), %rdi
callq 0x1147a8
leaq 0x163f(%rsp), %rdi
callq 0x114790
jmp 0x11be9e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1668(%rsp)
movl %eax, 0x1664(%rsp)
jmp 0x11be9e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1668(%rsp)
movl %eax, 0x1664(%rsp)
jmp 0x11be91
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1668(%rsp)
movl %eax, 0x1664(%rsp)
jmp 0x11bdc5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1668(%rsp)
movl %eax, 0x1664(%rsp)
jmp 0x11bdb8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1668(%rsp)
movl %eax, 0x1664(%rsp)
jmp 0x11bdab
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1668(%rsp)
movl %eax, 0x1664(%rsp)
jmp 0x11bd9e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1668(%rsp)
movl %eax, 0x1664(%rsp)
jmp 0x11bd91
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1668(%rsp)
movl %eax, 0x1664(%rsp)
jmp 0x11bd84
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1668(%rsp)
movl %eax, 0x1664(%rsp)
jmp 0x11bd77
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1668(%rsp)
movl %eax, 0x1664(%rsp)
leaq 0xb28(%rsp), %rdi
callq 0x1147a8
leaq 0xb27(%rsp), %rdi
callq 0x114790
leaq 0xb50(%rsp), %rdi
callq 0x1147a8
leaq 0xb4f(%rsp), %rdi
callq 0x114790
leaq 0xb78(%rsp), %rdi
callq 0x1147a8
leaq 0xb77(%rsp), %rdi
callq 0x114790
leaq 0xba0(%rsp), %rdi
callq 0x1147a8
leaq 0xb9f(%rsp), %rdi
callq 0x114790
leaq 0xbc0(%rsp), %rdi
callq 0x11c7b0
jmp 0x11be91
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1668(%rsp)
movl %eax, 0x1664(%rsp)
leaq 0xaff(%rsp), %rdi
callq 0x114790
jmp 0x11be91
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1668(%rsp)
movl %eax, 0x1664(%rsp)
jmp 0x11be84
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1668(%rsp)
movl %eax, 0x1664(%rsp)
jmp 0x11be77
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1668(%rsp)
movl %eax, 0x1664(%rsp)
leaq 0x60(%rsp), %rdi
callq 0x11d2b0
jmp 0x11be77
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1668(%rsp)
movl %eax, 0x1664(%rsp)
leaq 0x1b0(%rsp), %rdi
callq 0x11dbd0
leaq 0xad8(%rsp), %rdi
callq 0x11ddd0
leaq 0xb00(%rsp), %rdi
callq 0x1147a8
leaq 0xc50(%rsp), %rdi
callq 0x11de10
leaq 0x1698(%rsp), %rdi
callq 0x11dea0
leaq 0x1700(%rsp), %rdi
callq 0x11ded0
movq 0x1668(%rsp), %rdi
callq 0x114450
nopw %cs:(%rax,%rax)
nop