aboutsummaryrefslogtreecommitdiff
path: root/src/reduce.c
diff options
context:
space:
mode:
authorMarvin Borner2023-05-29 16:51:35 +0200
committerMarvin Borner2023-05-29 16:51:35 +0200
commit5575fbc92dd3076f5ed3f44e6e041c6074a71fd1 (patch)
tree3d62c965d025ea11064debc3d9d109bc26958e50 /src/reduce.c
parentf1dc637384f91bffe2342b8717c68b2f2cd2203e (diff)
Started reducer
has some problems still
Diffstat (limited to 'src/reduce.c')
-rw-r--r--src/reduce.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/src/reduce.c b/src/reduce.c
new file mode 100644
index 0000000..a927b12
--- /dev/null
+++ b/src/reduce.c
@@ -0,0 +1,56 @@
+// Copyright (c) 2023, Marvin Borner <dev@marvinborner.de>
+// SPDX-License-Identifier: MIT
+
+#include <stdio.h>
+
+#include <term.h>
+#include <reduce.h>
+#include <log.h>
+
+static struct term *substitute(struct term *term, struct term *substitution,
+ size_t level)
+{
+ if (term->type == VAR && term->u.var.index == level) {
+ return substitution;
+ } else if (term->type == ABS) {
+ struct term *new =
+ substitute(term->u.abs.term, substitution, level + 1);
+ return term_rehash_abs(term, new);
+ } else if (term->type == APP) {
+ struct term *lhs =
+ substitute(term->u.app.lhs, substitution, level);
+ struct term *rhs =
+ substitute(term->u.app.rhs, substitution, level);
+ return term_rehash_app(term, lhs, rhs);
+ }
+ fatal("invalid type %d\n", term->type);
+}
+
+static struct term *reduce_app(struct term *term)
+{
+ if (term->u.app.lhs->type == ABS) {
+ return substitute(term->u.app.lhs->u.abs.term, term->u.app.rhs,
+ 0);
+ } else {
+ struct term *lhs = reduce(term->u.app.lhs);
+ struct term *rhs = reduce(term->u.app.rhs);
+ return term_rehash_app(term, lhs, rhs);
+ }
+}
+
+static struct term *reduce_abs(struct term *term)
+{
+ return reduce(term->u.abs.term);
+}
+
+struct term *reduce(struct term *term)
+{
+ if (term->type == APP) {
+ return reduce_app(term);
+ } else if (term->type == ABS) {
+ return reduce_abs(term);
+ } else if (term->type == VAR) {
+ return term;
+ }
+ fatal("invalid type %d\n", term->type);
+}