-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathde_morgan_law.cpp
More file actions
146 lines (117 loc) · 4.48 KB
/
Copy pathde_morgan_law.cpp
File metadata and controls
146 lines (117 loc) · 4.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// Logicwise
// Copyright (c) 2026 Frog Singing (@frog-singing)
// SPDX-License-Identifier: MIT
#include <logicwise.h>
#include <concepts> // std::same_as, std::derived_from, std::convertible_to
#include <type_traits> // std::true_type
#include <iostream> // std::cout, std::endl
// If this file compiles successfully, then all logical assertions have passed.
namespace logicwise::test
{
using namespace logicwise::quantifier;
using namespace logicwise::arrangement;
using namespace logicwise::wrapper;
//--------------------------------------------------------------------------------
inline constexpr auto logical_conjunction = [] <valuewise::List PredicateList> { return
[] <typename Variable> { return
rangewise<all_of, element> // all_of: ∀
::template in<PredicateList>()
.satisfies([] <auto Predicate> { return Predicate.template operator() < Variable > (); });
};
};
inline constexpr auto logical_disjunction = [] <valuewise::List PredicateList> { return
[] <typename Variable> { return
rangewise<any_of, element> // any_of: ∃
::template in<PredicateList>()
.satisfies([] <auto Predicate> { return Predicate.template operator() < Variable > (); });
};
};
inline constexpr auto logical_conjunction_of_negation = [] <valuewise::List PredicateList> { return
[] <typename Variable> { return
rangewise<none_of, element> // none_of: ∀¬
::template in<PredicateList>()
.satisfies([] <auto Predicate> { return Predicate.template operator() < Variable > (); });
};
};
inline constexpr auto logical_disjunction_of_negation = [] <valuewise::List PredicateList> { return
[] <typename Variable> { return
rangewise<not_every, element> // not_every: ∃¬
::template in<PredicateList>()
.satisfies([] <auto Predicate> { return Predicate.template operator() < Variable > (); });
};
};
//--------------------------------------------------------------------------------
struct A { int x{}; };
}
int main()
{
using namespace logicwise;
using namespace logicwise::quantifier;
using namespace logicwise::arrangement;
using namespace logicwise::wrapper; // including type_value_pair
using namespace logicwise::test;
// variable list --------------------------------------------------------------------------------
using type_value_pair_list = type_list<
type_value_pair<int, 42>,
type_value_pair<A, A{42}>,
type_value_pair<A, nullptr>,
std::true_type // { std::integral_constant<bool, true>, true }
>;
// try to add more type-value pairs
// predicate list --------------------------------------------------------------------------------
static constexpr auto consistency = [] <typename T, auto V> {
return std::same_as<T, decltype(V)>;
};
static constexpr auto inheritance = [] <typename T, auto V> {
return std::derived_from<decltype(V), T>;
};
static constexpr auto convertibility = [] <typename T, auto V> {
return std::convertible_to<decltype(V), T>;
};
static constexpr auto constructibility = [] <typename T, auto V> {
return requires { T{ V }; };
};
// try to add more type-value relations
static constexpr auto to_property = [] <auto Relation> { return
[] <typename TypeValuePair> {
return Relation.template operator()
< typename TypeValuePair::type, TypeValuePair::value > ();
};
};
using property_list = value_list<
consistency,
inheritance,
convertibility,
constructibility
>::transform<to_property>;
// De Morgan's Law --------------------------------------------------------------------------------
static_assert(
rangewise<all_of, element>
::in<type_value_pair_list>()
.satisfies([] <typename TypeValuePair> { return
not logical_conjunction
.template operator() < property_list > ()
.template operator() < TypeValuePair > ()
==
logical_disjunction_of_negation
.template operator() < property_list > ()
.template operator() < TypeValuePair > ();
}),
"De Morgan's First Law: not (P1 and P2 and ... and Pn) ≡ (not P1) or (not P2) or ... or (not Pn)"
);
static_assert(
rangewise<all_of, element>
::in<type_value_pair_list>()
.satisfies([] <typename TypeValuePair> { return
not logical_disjunction
.template operator() < property_list > ()
.template operator() < TypeValuePair > ()
==
logical_conjunction_of_negation
.template operator() < property_list > ()
.template operator() < TypeValuePair > ();
}),
"De Morgan's Second Law: not (P1 or P2 or ... or Pn) ≡ (not P1) and (not P2) and ... and (not Pn)"
);
std::cout << std::endl << "Hello Logic!" << std::endl;
}