-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild_logical_expr.js
72 lines (60 loc) · 2.18 KB
/
build_logical_expr.js
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
function calculate_logical_expression(expression, vars) {
/*
The variable is a single latin letter, takes the value 0 or 1
The binary functions:
~, ¬ negation
*, ∧, & conjunction
+, ∨ disjunction
^, ⨁ exclusive disjunction
|, ↑ alternative denial
/, ↓ joint denial
->, → implication, <-, ← converse implication
=, ≡ biconditional
*/
// remove spaces and replace variables with their values
var expr = expression.replaceAll(/\s/g, '')
for (const i in vars) expr = expr.replaceAll(vars[i].name, vars[i].val)
// open the brackets by recursion
function find_brackets_content(str) {
// assumed that the first character is an opening bracket
for (var i=1; i<str.length; i++) {
for (var brc=1; brc != 0 && i<str.length; i++) {
if (str[i] == '(') brc++
else if (str[i] == ')') brc--
}
if (brc != 0) return null
return str.slice(1, i-1)
}
}
for (var i=0; i<expr.length; i++) {
if (expr[i] == '(') {
var brc_content = find_brackets_content(expr.substr(i)); if (brc_content == null) return null
var brc_expr_res = calculate_logical_expression(brc_content, vars); if (brc_expr_res == null) return null
expr = expr.slice(0, i) + brc_expr_res + expr.substr(i+brc_content.length+2)
}
else if (expr[i] == ')') return null
}
// linear transformations
const operations = [
{ reg: /[~¬][01]/, func: (_, a) => (a^1) },
{ reg: /[01][\*∧&][01]/, func: (a, b) => (+a * +b) },
{ reg: /[01][\+∨][01]/, func: (a, b) => (Math.min(+a + +b, 1)) },
{ reg: /[01][\^⨁][01]/, func: (a, b) => (a ^ b) },
{ reg: /[01][\|↑][01]/, func: (a, b) => (+a * +b)^1 },
{ reg: /[01][/↓][01]/, func: (a, b) => (Math.min(+a + +b, 1))^1 },
{ reg: /[01](->|→)[01]/, func: (a, b) => (+(a <= b)) },
{ reg: /[01](<-|←)[01]/, func: (a, b) => (+(a >= b)) },
{ reg: /[01][=≡][01]/, func: (a, b) => (+(a == b)) },
]
for (var op in operations) {
op = operations[op]
var match = expr.match(op.reg)
while (match != null) {
expr = expr.replace(op.reg, op.func(match[0][0], match[0].slice(-1)))
match = expr.match(op.reg)
}
}
// some syntax error
if (expr.length > 1 || !/\d/.test(expr)) return null
return expr
}