aboutsummaryrefslogtreecommitdiffstats
path: root/libnormalform_and2__.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libnormalform_and2__.c119
1 files changed, 119 insertions, 0 deletions
diff --git a/libnormalform_and2__.c b/libnormalform_and2__.c
new file mode 100644
index 0000000..c20eb3e
--- /dev/null
+++ b/libnormalform_and2__.c
@@ -0,0 +1,119 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+/**
+ * See `.inverse` in `struct libnormalform_sentence` (AND implementation)
+ */
+static LIBNORMALFORM_SENTENCE *
+and_inverse(LIBNORMALFORM_SENTENCE *this)
+{
+ /* ¬(ab) = ¬a + ¬b */
+ LIBNORMALFORM_SENTENCE *l, *r, *ret;
+ l = this->data.binary.l->inverse(this->data.binary.l);
+ if (!l)
+ return NULL;
+ r = this->data.binary.r->inverse(this->data.binary.r);
+ if (!r) {
+ libnormalform_free(l);
+ return NULL;
+ }
+ ret = libnormalform_or2__(l, r);
+ if (ret && this->atom) {
+ ret->atom = this->atom;
+ ret->atom->refcount += 1;
+ }
+ return ret;
+}
+
+
+/**
+ * See `.equals` in `struct libnormalform_sentence` (AND implementation)
+ */
+static int
+and_equals(LIBNORMALFORM_SENTENCE *this, LIBNORMALFORM_SENTENCE *other, int *inv_out)
+{
+ LIBNORMALFORM_SENTENCE *tl, *tr;
+ LIBNORMALFORM_SENTENCE *ol, *or;
+ int inv;
+
+ if (other->type != TYPE_AND && other->type != TYPE_OR)
+ return other->type == TYPE_XOR && other->equals(other, this, inv_out);
+
+ tl = this->data.binary.l;
+ tr = this->data.binary.r;
+ ol = other->data.binary.l;
+ or = other->data.binary.r;
+
+ if (tl->hash != ol->hash || tr->hash != or->hash)
+ return 0;
+
+ if (!tl->equals(tl, ol, inv_out)) {
+ if (tl->hash == tr->hash) {
+ ol = other->data.binary.r;
+ or = other->data.binary.l;
+ if (!tl->equals(tl, ol, inv_out))
+ return 0;
+ } else {
+ return 0;
+ }
+ }
+ if (!tr->equals(tr, or, &inv))
+ return 0;
+ return inv == *inv_out && inv == (other->type == TYPE_OR);
+}
+
+
+/**
+ * See `.evaluate` in `struct libnormalform_sentence` (AND implementation)
+ */
+static int
+and_evaluate(LIBNORMALFORM_SENTENCE *this, void *input)
+{
+ int r = this->data.binary.l->evaluate(this->data.binary.l, input);
+ return r <= 0 ? r : this->data.binary.r->evaluate(this->data.binary.r, input);
+}
+
+
+LIBNORMALFORM_SENTENCE *
+(libnormalform_and2__)(LIBNORMALFORM_SENTENCE *l, LIBNORMALFORM_SENTENCE *r)
+{
+ static const struct libnormalform_sentence prototype = {
+ PROTOTYPE_COMMON,
+ .type = TYPE_AND,
+ .inverse = &and_inverse,
+ .equals = &and_equals,
+ .evaluate = &and_evaluate
+ };
+
+ LIBNORMALFORM_SENTENCE *ret = malloc(sizeof(*ret));
+ if (!ret) {
+ libnormalform_free(l);
+ libnormalform_free(r);
+ return NULL;
+ }
+ *ret = prototype;
+ ret->hash = AND_OR_HASH(l, r);
+ if (l->hash <= r->hash) {
+ ret->data.binary.l = l;
+ ret->data.binary.r = r;
+ } else {
+ ret->data.binary.l = r;
+ ret->data.binary.r = l;
+ }
+ return ret;
+}
+
+
+#else
+
+
+CONST int
+main(void)
+{
+ return 0; /* indirectly tested */
+}
+
+
+#endif