about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNguyễn Gia Phong <cnx@loang.net>2025-10-19 16:14:16 +0900
committerNguyễn Gia Phong <cnx@loang.net>2025-10-19 16:14:16 +0900
commitd64b339e1d9e74d92821ec069e95093ac03bb25d (patch)
tree0d5dc42c8ec0f9bf26fe28aa8fb8578eb39ae4eb
parentf4c491fce28223a09900aafeb6e1e83994df2bbd (diff)
downloadtaosc-d64b339e1d9e74d92821ec069e95093ac03bb25d.tar.gz
Narrow predicate space by a few orders of magnitude
-rw-r--r--Variables.zig39
-rw-r--r--synth.zig61
2 files changed, 50 insertions, 50 deletions
diff --git a/Variables.zig b/Variables.zig
index 9732afa..d23f1f4 100644
--- a/Variables.zig
+++ b/Variables.zig
@@ -140,23 +140,10 @@ pub const Query = union(enum) {
     register: RegisterEnum,
     stack: usize,
 
-    pub fn all(allocator: Allocator) Allocator.Error![]Query {
-        const constants = tags(ConstantEnum);
-        const registers = tags(RegisterEnum);
-        const n = constants.len + registers.len;
-        const queries = try allocator.alloc(Query, n);
-        for (queries[0..constants.len], constants) |*dest, src|
-            dest.* = .{ .constant = src };
-        for (queries[constants.len..][0..registers.len],
-             registers) |*dest, src|
-            dest.* = .{ .register = src };
-        return queries;
-    }
-
     pub fn skip(q: Query, r: Query, s: Query) bool {
-        return eql(q, r) or eql(r, s) or eql(s, q)
-            or q == .constant and r == .constant and s == .constant
-            or q != .constant and r != .constant and s != .constant;
+        return eql(r, s)
+            or r == .constant and s == .constant
+            or (r == .constant or s == .constant) and q.constant != .max1;
     }
 
     pub fn format(query: Query, writer: *Writer) Writer.Error!void {
@@ -168,6 +155,26 @@ pub const Query = union(enum) {
     }
 };
 
+pub fn constantQueries() []Query {
+    var queries: [tags(ConstantEnum).len]Query = undefined;
+    for (&queries, tags(ConstantEnum)) |*dest, src|
+        dest.* = .{ .constant = src };
+    return &queries;
+}
+
+pub fn allQueries(allocator: Allocator) Allocator.Error![]Query {
+    const constants = tags(ConstantEnum);
+    const registers = tags(RegisterEnum);
+    const n = constants.len + registers.len;
+    const queries = try allocator.alloc(Query, n);
+    for (queries[0..constants.len], constants) |*dest, src|
+        dest.* = .{ .constant = src };
+    for (queries[constants.len..][0..registers.len],
+         registers) |*dest, src|
+        dest.* = .{ .register = src };
+    return queries;
+}
+
 pub fn get(variables: Variables, query: Query,
            tmp: []Register) ![]const Register {
     switch (query) {
diff --git a/synth.zig b/synth.zig
index e82f85b..5f33c6a 100644
--- a/synth.zig
+++ b/synth.zig
@@ -89,9 +89,9 @@ const ArithmeticOperator = enum {
 };
 
 const Arithmetic = struct {
-    lhs: Unary,
+    lhs: Variables.Query,
     op: ArithmeticOperator,
-    rhs: Unary,
+    rhs: Variables.Query,
 
     pub fn format(arith: Arithmetic, writer: *Writer) Writer.Error!void {
         try writer.print("{f} {s} {f}", .{
@@ -103,19 +103,17 @@ const Arithmetic = struct {
 };
 
 const Comparison = struct {
-    lhs: Unary,
+    lhs: Arithmetic,
     op: CompareOperator,
-    rhs: Arithmetic,
+    rhs: Unary,
 
     fn check(cmp: Comparison, vars: Variables, expected: bool,
              tmp: Temporaries) !bool {
-        for (try vars.get(cmp.lhs.val, tmp[0]),
-             try vars.get(cmp.rhs.lhs.val, tmp[1]),
-             try vars.get(cmp.rhs.rhs.val, tmp[2])) |v0, v1, v2| {
-            const arith = cmp.rhs.op.apply(cmp.rhs.lhs.op.apply(v1),
-                                           cmp.rhs.lhs.op.apply(v2)) catch
-                return false;
-            const actual = compare(cmp.lhs.op.apply(v0), cmp.op, arith);
+        for (try vars.get(cmp.lhs.lhs, tmp[0]),
+             try vars.get(cmp.lhs.rhs, tmp[1]),
+             try vars.get(cmp.rhs.val, tmp[2])) |v0, v1, v2| {
+            const arith = cmp.lhs.op.apply(v0, v1) catch return false;
+            const actual = compare(arith, cmp.op, cmp.rhs.op.apply(v2));
             if (if (expected) !actual else actual)
                 return false;
         }
@@ -141,18 +139,14 @@ const Comparison = struct {
 const Temporaries = [3][]Register;
 
 fn process(writer: *Writer, bot: Variables, top: Variables,
-           v0: Variables.Query, v1: Variables.Query, v2: Variables.Query,
-           o0: UnaryOperator, o1: UnaryOperator, o2: UnaryOperator,
-           arith: ArithmeticOperator, cmp: CompareOperator,
-           bot_tmp: Temporaries, top_tmp: Temporaries) !void {
+           bot_tmp: Temporaries, top_tmp: Temporaries,
+           v0: Variables.Query, arith: ArithmeticOperator,
+           v1: Variables.Query, cmp: CompareOperator,
+           unary: UnaryOperator, v2: Variables.Query) !void {
     const predicate = Comparison{
-        .lhs = .{ .op = o0, .val = v0 },
+        .lhs = .{ .lhs = v0, .op = arith, .rhs = v1 },
         .op = cmp,
-        .rhs = .{
-            .lhs = .{ .op = o1, .val = v1 },
-            .op = arith,
-            .rhs = .{ .op = o2, .val = v2 },
-        },
+        .rhs = .{ .op = unary, .val = v2 },
     };
     if (try predicate.check(bot, false, bot_tmp))
         return;
@@ -162,15 +156,14 @@ fn process(writer: *Writer, bot: Variables, top: Variables,
 }
 
 fn mineOperator(writer: *Writer, bot: Variables, top: Variables,
-                v0: Variables.Query, v1: Variables.Query, v2: Variables.Query,
-                bot_tmp: Temporaries, top_tmp: Temporaries) !void {
-    for (tags(UnaryOperator)) |o0|
-        for (tags(UnaryOperator)) |o1|
-            for (tags(UnaryOperator)) |o2|
-                for (tags(ArithmeticOperator)) |arith|
-                    for (tags(CompareOperator)) |cmp|
-                        try process(writer, bot, top, v0, v1, v2, o0, o1, o2,
-                                    arith, cmp, bot_tmp, top_tmp);
+                bot_tmp: Temporaries, top_tmp: Temporaries,
+                v0: Variables.Query, v1: Variables.Query,
+                v2: Variables.Query) !void {
+    for (tags(ArithmeticOperator)) |arith|
+        for (tags(UnaryOperator)) |unary|
+            for (tags(CompareOperator)) |cmp|
+                try process(writer, bot, top, bot_tmp, top_tmp,
+                            v0, arith, v1, cmp, unary, v2);
 }
 
 fn alloc_tmp(allocator: Allocator, len: usize) Allocator.Error!Temporaries {
@@ -193,11 +186,11 @@ fn mine(allocator: Allocator, writer: *Writer,
     const top_tmp = try alloc_tmp(allocator, top.samples);
     defer free_tmp(allocator, top_tmp);
 
-    const variables = try Variables.Query.all(allocator);
+    const variables = try Variables.allQueries(allocator);
     defer allocator.free(variables);
-    for (variables) |v0| for (variables) |v1| for (variables) |v2|
-        if (!v0.skip(v1, v2))
-            try mineOperator(writer, bot, top, v0, v1, v2, bot_tmp, top_tmp);
+    inline for (comptime Variables.constantQueries()) |v2|
+        for (variables) |v0| for (variables) |v1| if (!v2.skip(v0, v1))
+            try mineOperator(writer, bot, top, bot_tmp, top_tmp, v0, v1, v2);
     try writer.flush();
 }