-
Notifications
You must be signed in to change notification settings - Fork 0
/
DLSpec.groovy
93 lines (78 loc) · 2.44 KB
/
DLSpec.groovy
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
class DLSpec {
def structure = []
def isInstance
def negate = false
def ⊓(Object[] args) { buildJunction('⊓', args) }
def and(Object[] args) { ⊓(args) }
def ⊔(Object[] args) { buildJunction('⊔', args) }
def or(Object[] args) { ⊔(args) }
def ≥(amt, r, Object[] args) { buildQuantifier('≥', r, amt, args) }
def gt(amt, r, Object[] args) { ≥(amt, r, args) }
def ≤(amt, r, Object[] args) { buildQuantifier('≤', r, amt, args) }
def lt(amt, r, Object[] args) { ≤(amt, r, args) }
def ∃(r, Object[] args) { buildQuantifier('∃', r, null, args); }
def eq(r, Object[] args) { ∃(r, args) }
def ∀(r, Object[] args) { buildQuantifier('∀', r, null, args) }
def uq(r, Object[] args) { ∀(r, args) }
// Apparently we're not allowed to use ¬ as a function name.
def not(Object arg) {
if(arg instanceof String) {
structure << [
'type': 'literal',
'value': arg,
'negate': true
]
} else {
def dl = new DLSpec(negate:true)
def code = arg.rehydrate(dl, this, this)
code.resolveStrategy = Closure.DELEGATE_ONLY
code()
structure = dl.structure
}
}
private buildQuantifier(String quantifier, String r, amt, Object[] args) {
def rule = [:]
rule['type'] = 'operation'
rule['operation'] = quantifier
rule['relation'] = r
if(amt) {
rule['amount'] = amt
}
def definition = args[0]
if(definition instanceof String) {
rule['definition'] = [
'type': 'literal',
'value': definition,
'negate': negate
]
} else if(definition instanceof Closure) {
def dl = new DLSpec(negate:negate)
def code = definition.rehydrate(dl, this, this)
code.resolveStrategy = Closure.DELEGATE_ONLY
code()
rule['definition'] = dl.structure[0]
}
structure << rule
}
private buildJunction(String junction, Object[] args) {
def rule = [:]
rule['type'] = 'operation'
rule['operation'] = junction
['left':args[0], 'right':args[1]].each { i, x ->
if(x instanceof String) {
rule[i] = [
'type': 'literal',
'value': x,
'negate': negate
]
} else if(x instanceof Closure) {
def dl = new DLSpec(negate:negate)
def code = x.rehydrate(dl, this, this)
code.resolveStrategy = Closure.DELEGATE_ONLY
code()
rule[i] = dl.structure[0]
}
}
structure << rule
}
}