diff options
| author | Mattias Andrée <maandree@kth.se> | 2024-07-19 01:29:42 +0200 |
|---|---|---|
| committer | Mattias Andrée <maandree@kth.se> | 2024-07-19 01:29:42 +0200 |
| commit | 4294ec0ed06ee34920c9edaeebaeb8b65c720791 (patch) | |
| tree | e0cded59452597c04fb38f403745a384675cb5f9 /libnormalform_imply.c | |
| download | libnormalform-4294ec0ed06ee34920c9edaeebaeb8b65c720791.tar.gz libnormalform-4294ec0ed06ee34920c9edaeebaeb8b65c720791.tar.bz2 libnormalform-4294ec0ed06ee34920c9edaeebaeb8b65c720791.tar.xz | |
First commit
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to 'libnormalform_imply.c')
| -rw-r--r-- | libnormalform_imply.c | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/libnormalform_imply.c b/libnormalform_imply.c new file mode 100644 index 0000000..823abf7 --- /dev/null +++ b/libnormalform_imply.c @@ -0,0 +1,166 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +LIBNORMALFORM_SENTENCE * +(libnormalform_imply)(LIBNORMALFORM_SENTENCE **xs) +{ + LIBNORMALFORM_SENTENCE *t; + size_t n = 0, i; + + while (xs[n]) + n += 1; + + if (!n) { + /* 1 → x = x and 0 → x = 1 */ + return libnormalform_true(); + } + + /* a → b → c = a → (b → c) = (b → c) ← a = (c ← b) ← a = c ← b ← a */ + for (i = 0; i < n--; i++) { + t = xs[i]; + xs[i] = xs[n]; + xs[n] = t; + } + return libnormalform_if(xs); +} + + +#else + + +#define IMPLY(...) LIBNORMALFORM_IMPLY(__VA_ARGS__) + + +int +main(void) +{ + struct libnormalform_variable var1, var2, var3; + LIBNORMALFORM_SENTENCE *a, *b, *v1, *v2, *v3; + LIBNORMALFORM_SENTENCE *ts, *fs; + + ASSUME(v1 = libnormalform_variable(&var1)); + ASSUME(v2 = libnormalform_variable(&var2)); + ASSUME(v3 = libnormalform_variable(&var3)); + ASSUME(ts = libnormalform_true()); + ASSUME(fs = libnormalform_false()); + +#ifdef USE_CHECKED_VERSION + errno = 0; + ASSERT(!IMPLY(REF(v1), NULL) && errno == 0); + errno = 1; + ASSERT(!IMPLY(REF(v1), NULL) && errno == 1); + errno = 0; + ASSERT(!IMPLY(NULL, REF(v1)) && errno == 0); + errno = 1; + ASSERT(!IMPLY(NULL, REF(v1)) && errno == 1); + errno = 0; + ASSERT(!IMPLY(NULL, NULL) && errno == 0); + errno = 1; + ASSERT(!IMPLY(NULL, NULL) && errno == 1); +#endif + +#define T REF(ts) +#define F REF(fs) +#define TV LIBNORMALFORM_TRUE +#define FV LIBNORMALFORM_FALSE + +#define ASSERT_CONST(VALUE, ...)\ + do {\ + ASSUME(a = IMPLY(__VA_ARGS__));\ + ASSERT(a->type == TYPE_##VALUE);\ + libnormalform_free(a);\ + } while (0) + +#define ASSERT_EVAL2(VALUE, V1, V2)\ + do {\ + ASSUME(a = IMPLY(REF(v1), REF(v2)));\ + ASSERT(a->type != TYPE_TRUE && a->type != TYPE_FALSE);\ + var1.value = V1##V;\ + var2.value = V2##V;\ + ASSERT(libnormalform_evaluate(a) == (int)LIBNORMALFORM_##VALUE);\ + libnormalform_free(a);\ + } while (0) + +#ifndef USE_TWO + +#if defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wformat" +#endif + + ASSERT_CONST(TRUE); /* IMPLY () -> TRUE */ + +#if defined(__GNUC__) +# pragma GCC diagnostic pop +#endif + + ASSERT_CONST(TRUE, T); /* IMPLY (TRUE) -> TRUE */ + ASSERT_CONST(FALSE, F); /* IMPLY (FALSE) -> FALSE */ + +#endif + + ASSERT_CONST(TRUE, F, F); /* IMPLY (FALSE, FALSE) -> TRUE */ + ASSERT_CONST(TRUE, F, T); /* IMPLY (FALSE, TRUE) -> TRUE */ + ASSERT_CONST(FALSE, T, F); /* IMPLY (TRUE, FALSE) -> FALSE */ + ASSERT_CONST(TRUE, T, T); /* IMPLY (TRUE, TRUE) -> TRUE */ + + ASSERT_EVAL2(TRUE, F, F); /* IMPLY (var(FALSE), var(FALSE)) => TRUE */ + ASSERT_EVAL2(TRUE, F, T); /* IMPLY (var(FALSE), var(TRUE)) => TRUE */ + ASSERT_EVAL2(FALSE, T, F); /* IMPLY (var(TRUE), var(FALSE)) => FALSE */ + ASSERT_EVAL2(TRUE, T, T); /* IMPLY (var(TRUE), var(TRUE)) => TRUE */ + +#ifndef USE_TWO + + /* IMPLY (x) -> x */ + ASSUME(a = IMPLY(REF(v1))); + ASSERT(a == v1); + ASSERT(a->refcount == 2); + libnormalform_free(a); + +#endif + + /* IMPLY (x, y) -> IF (y, x) */ + ASSUME(a = IMPLY(REF(v1), REF(v2))); + ASSUME(b = libnormalform_if2(REF(v2), REF(v1))); + ASSERT_EQUAL(a, b); + libnormalform_free(a); + libnormalform_free(b); + +#ifndef USE_TWO + + /* IMPLY (x, y, z) -> IF (z, y, x) */ + ASSUME(a = IMPLY(REF(v1), REF(v2), REF(v3))); + ASSUME(b = libnormalform_ifl(REF(v3), REF(v2), REF(v1), NULL)); + ASSERT_EQUAL(a, b); + libnormalform_free(a); + libnormalform_free(b); + + /* IMPLY (x, y) -> independence from IMPLY (y, x) */ + ASSUME(a = IMPLY(REF(v1), REF(v2))); + ASSUME(b = IMPLY(REF(v2), REF(v1))); + ASSERT_NOTEQUAL(a, b); + libnormalform_free(a); + libnormalform_free(b); + +#endif + +#undef T +#undef F +#undef TV +#undef FV + +#undef ASSERT_CONST +#undef ASSERT_EVAL2 + + libnormalform_free(v1); + libnormalform_free(v2); + libnormalform_free(v3); + libnormalform_free(ts); + libnormalform_free(fs); + return 0; +} + + +#endif |
