Skip to content

Commit 1c9f97b

Browse files
bogglebrson
authored andcommitted
stdlib: added (2,3,4)-valued logic ADTs
This is useful for writing caches and perhaps in typestate predicates. It also adds a companion module for bool with from_str, to_str, ... fns.
1 parent beced36 commit 1c9f97b

File tree

8 files changed

+848
-2
lines changed

8 files changed

+848
-2
lines changed

src/lib/bool.rs

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
// -*- rust -*-
2+
3+
/*
4+
Module: bool
5+
6+
Classic Boolean logic reified as ADT
7+
*/
8+
9+
export t;
10+
export not, and, or, xor, implies;
11+
export eq, ne, is_true, is_false;
12+
export from_str, to_str, all_values, to_bit;
13+
14+
/*
15+
Type: t
16+
17+
The type of boolean logic values
18+
*/
19+
type t = bool;
20+
21+
/* Function: not
22+
23+
Negation/Inverse
24+
*/
25+
pure fn not(v: t) -> t { !v }
26+
27+
/* Function: and
28+
29+
Conjunction
30+
*/
31+
pure fn and(a: t, b: t) -> t { a && b }
32+
33+
/* Function: and
34+
35+
Disjunction
36+
*/
37+
pure fn or(a: t, b: t) -> t { a || b }
38+
39+
/*
40+
Function: xor
41+
42+
Exclusive or, i.e. `or(and(a, not(b)), and(not(a), b))`
43+
*/
44+
pure fn xor(a: t, b: t) -> t { (a && !b) || (!a && b) }
45+
46+
/*
47+
Function: implies
48+
49+
Implication in the logic, i.e. from `a` follows `b`
50+
*/
51+
pure fn implies(a: t, b: t) -> t { !a || b }
52+
53+
/*
54+
Predicate: eq
55+
56+
Returns:
57+
58+
true if truth values `a` and `b` are indistinguishable in the logic
59+
*/
60+
pure fn eq(a: t, b: t) -> bool { a == b }
61+
62+
/*
63+
Predicate: ne
64+
65+
Returns:
66+
67+
true if truth values `a` and `b` are distinguishable in the logic
68+
*/
69+
pure fn ne(a: t, b: t) -> bool { a != b }
70+
71+
/*
72+
Predicate: is_true
73+
74+
Returns:
75+
76+
true if `v` represents truth in the logic
77+
*/
78+
pure fn is_true(v: t) -> bool { v }
79+
80+
/*
81+
Predicate: is_false
82+
83+
Returns:
84+
85+
true if `v` represents falsehood in the logic
86+
*/
87+
pure fn is_false(v: t) -> bool { !v }
88+
89+
/*
90+
Function: from_str
91+
92+
Parse logic value from `s`
93+
*/
94+
pure fn from_str(s: str) -> t {
95+
alt s {
96+
"true" { true }
97+
"false" { false }
98+
}
99+
}
100+
101+
/*
102+
Function: to_str
103+
104+
Convert `v` into a string
105+
*/
106+
pure fn to_str(v: t) -> str { if v { "true" } else { "false" } }
107+
108+
/*
109+
Function: all_values
110+
111+
Iterates over all truth values by passing them to `blk`
112+
in an unspecified order
113+
*/
114+
fn all_values(blk: block(v: t)) {
115+
blk(true);
116+
blk(false);
117+
}
118+
119+
/*
120+
Function: to_bit
121+
122+
Returns:
123+
124+
An u8 whose first bit is set if `if_true(v)` holds
125+
*/
126+
fn to_bit(v: t) -> u8 { if v { 1u8 } else { 0u8 } }
127+
128+
// Local Variables:
129+
// mode: rust;
130+
// fill-column: 78;
131+
// indent-tabs-mode: nil
132+
// c-basic-offset: 4
133+
// buffer-file-coding-system: utf-8-unix
134+
// End:

src/lib/four.rs

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
// -*- rust -*-
2+
3+
/*
4+
Module: four
5+
6+
The fourrternary Belnap relevance logic FOUR represented as ADT
7+
8+
This allows reasoning with four logic values (true, false, none, both)
9+
10+
Implementation: Truth values are represented using a single u8 and
11+
all operations are done using bitshifting which is fast
12+
on current cpus.
13+
*/
14+
15+
import tri;
16+
17+
export t, none, true, false, both;
18+
export not, and, or, xor, implies, implies_materially;
19+
export eq, ne, is_true, is_false;
20+
export from_str, to_str, all_values, to_trit, to_bit;
21+
22+
/*
23+
Type: t
24+
25+
The type of fourrternary logic values
26+
27+
It may be thought of as tuple `(y, x)` of two bools
28+
29+
*/
30+
type t = u8;
31+
32+
const b0: u8 = 1u8;
33+
const b1: u8 = 2u8;
34+
const b01: u8 = 3u8;
35+
36+
/*
37+
Constant: none
38+
39+
Logic value `(0, 0)` for bottom (neither true or false)
40+
*/
41+
const none: t = 0u8;
42+
43+
/*
44+
Constant: true
45+
46+
Logic value `(0, 1)` for truth
47+
*/
48+
const true: t = 1u8;
49+
50+
/*
51+
Constant: false
52+
53+
Logic value `(1, 0)` for falsehood
54+
*/
55+
const false: t = 2u8;
56+
57+
/*
58+
Constant: both
59+
60+
Logic value `(1, 1)` for top (both true and false)
61+
*/
62+
const both: t = 3u8;
63+
64+
/* Function: not
65+
66+
Negation/Inverse
67+
68+
Returns:
69+
70+
`'(v.y, v.x)`
71+
*/
72+
pure fn not(v: t) -> t { ((v << 1u8) | (v >> 1u8)) & b01 }
73+
74+
/* Function: and
75+
76+
Conjunction
77+
78+
Returns:
79+
80+
`(a.x | b.x, a.y & b.y)`
81+
*/
82+
pure fn and(a: t, b: t) -> t { ((a & b) & b0) | ((a | b) & b1) }
83+
84+
/* Function: or
85+
86+
Disjunction
87+
88+
Returns:
89+
90+
`(a.x & b.x, a.y | b.y)`
91+
*/
92+
pure fn or(a: t, b: t) -> t { ((a | b) & b0) | ((a & b) & b1) }
93+
94+
/* Function: xor
95+
96+
Classic exclusive or
97+
98+
Returns:
99+
100+
`or(and(a, not(b)), and(not(a), b))`
101+
*/
102+
pure fn xor(a: t, b: t) -> t { or(and(a, not(b)), and(not(a), b)) }
103+
104+
/*
105+
Function: implies
106+
107+
Strong implication (from `a` strongly follows `b`)
108+
109+
Returns:
110+
111+
`( x1 & y2, !x1 | x2)`
112+
*/
113+
pure fn implies(a: t, b: t) -> t { ((a << 1u8) & b & b1) | (((!a) | b) & b0) }
114+
115+
/*
116+
Function: implies_materially
117+
118+
Classic (material) implication in the logic
119+
(from `a` materially follows `b`)
120+
121+
Returns:
122+
123+
`or(not(a), b)`
124+
*/
125+
pure fn implies_materially(a: t, b: t) -> t { or(not(a), b) }
126+
127+
/*
128+
Predicate: eq
129+
130+
Returns:
131+
132+
true if truth values `a` and `b` are indistinguishable in the logic
133+
*/
134+
pure fn eq(a: t, b: t) -> bool { a == b }
135+
136+
/*
137+
Predicate: ne
138+
139+
Returns:
140+
141+
true if truth values `a` and `b` are distinguishable in the logic
142+
*/
143+
pure fn ne(a: t, b: t) -> bool { a != b }
144+
145+
/*
146+
Predicate: is_true
147+
148+
Returns:
149+
150+
true if `v` represents truth in the logic (is `true` or `both`)
151+
*/
152+
pure fn is_true(v: t) -> bool { (v & b0) != 0u8 }
153+
154+
/*
155+
Predicate: is_false
156+
157+
Returns:
158+
159+
true if `v` represents falsehood in the logic (is `false` or `none`)
160+
*/
161+
pure fn is_false(v: t) -> bool { (v & b0) == 0u8 }
162+
163+
/*
164+
Function: from_str
165+
166+
Parse logic value from `s`
167+
*/
168+
pure fn from_str(s: str) -> t {
169+
alt s {
170+
"none" { none }
171+
"false" { four::false }
172+
"true" { four::true }
173+
"both" { both }
174+
}
175+
}
176+
177+
/*
178+
Function: to_str
179+
180+
Convert `v` into a string
181+
*/
182+
pure fn to_str(v: t) -> str {
183+
// FIXME replace with consts as soon as that works
184+
alt v {
185+
0u8 { "none" }
186+
1u8 { "true" }
187+
2u8 { "false" }
188+
3u8 { "both" }
189+
}
190+
}
191+
192+
/*
193+
Function: all_values
194+
195+
Iterates over all truth values by passing them to `blk`
196+
in an unspecified order
197+
*/
198+
fn all_values(blk: block(v: t)) {
199+
blk(both);
200+
blk(four::true);
201+
blk(four::false);
202+
blk(none);
203+
}
204+
205+
/*
206+
Function: to_bit
207+
208+
Returns:
209+
210+
An u8 whose first bit is set if `if_true(v)` holds
211+
*/
212+
fn to_bit(v: t) -> u8 { v & b0 }
213+
214+
/*
215+
Function: to_tri
216+
217+
Returns:
218+
219+
A trit of `v` (`both` and `none` are both coalesced into `trit::unknown`)
220+
*/
221+
fn to_trit(v: t) -> tri::t { v & (v ^ not(v)) }
222+
223+
// Local Variables:
224+
// mode: rust;
225+
// fill-column: 78;
226+
// indent-tabs-mode: nil
227+
// c-basic-offset: 4
228+
// buffer-file-coding-system: utf-8-unix
229+
// End:

src/lib/std.rc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
#[license = "BSD"];
88

99

10-
export box, char, float, int, str, ptr, uint, u8, u32, u64, vec;
10+
export box, char, float, int, str, ptr, uint, u8, u32, u64, vec, bool;
1111
export comm, fs, io, net, run, sys, task;
12-
export ctypes, either, option, result, util;
12+
export ctypes, either, option, result, four, tri, util;
1313
export bitv, deque, fun_treemap, list, map, smallintmap, sort, treemap, ufind;
1414
export rope;
1515
export ebml, dbg, getopts, json, math, rand, sha1, term, time, unsafe;
@@ -30,6 +30,7 @@ mod uint;
3030
mod u8;
3131
mod u32;
3232
mod u64;
33+
mod bool;
3334
mod vec;
3435

3536

@@ -50,6 +51,8 @@ mod ctypes;
5051
mod either;
5152
mod option;
5253
mod result;
54+
mod four;
55+
mod tri;
5356
mod util;
5457

5558

0 commit comments

Comments
 (0)