occam-verify-cli 1.0.617 → 1.0.632
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/context/ephemeral.js +152 -47
- package/lib/context/file/nominal.js +136 -140
- package/lib/context/liminal.js +16 -26
- package/lib/context/scoped.js +26 -55
- package/lib/context.js +103 -53
- package/lib/element/assertion/contained.js +3 -1
- package/lib/element/assertion/defined.js +5 -3
- package/lib/element/assertion/property.js +10 -58
- package/lib/element/assertion/satisfies.js +3 -1
- package/lib/element/assertion/subproof.js +3 -1
- package/lib/element/assertion/type.js +65 -109
- package/lib/element/assumption.js +40 -16
- package/lib/element/constructor/bracketed.js +13 -53
- package/lib/element/constructor.js +5 -5
- package/lib/element/declaration/constructor.js +5 -2
- package/lib/element/derivation.js +8 -10
- package/lib/element/equality.js +102 -62
- package/lib/element/equivalence.js +6 -6
- package/lib/element/equivalences.js +4 -4
- package/lib/element/frame.js +21 -21
- package/lib/element/hypothesis.js +5 -7
- package/lib/element/judgement.js +47 -25
- package/lib/element/metaType.js +2 -2
- package/lib/element/metavariable.js +12 -3
- package/lib/element/propertyRelation.js +3 -3
- package/lib/element/reference.js +9 -21
- package/lib/element/rule.js +13 -15
- package/lib/element/signature.js +5 -5
- package/lib/element/statement.js +23 -25
- package/lib/element/subDerivation.js +4 -6
- package/lib/element/substitution/frame.js +4 -4
- package/lib/element/substitution/reference.js +4 -4
- package/lib/element/substitution/statement.js +4 -4
- package/lib/element/substitution/term.js +9 -3
- package/lib/element/substitution.js +71 -43
- package/lib/element/term.js +20 -6
- package/lib/element/topLevelAssertion.js +9 -11
- package/lib/element/topLevelMetaAssertion.js +9 -11
- package/lib/element/variable.js +44 -3
- package/lib/process/assign.js +96 -26
- package/lib/process/unify.js +3 -4
- package/lib/process/validate.js +7 -7
- package/lib/process/verify.js +2 -2
- package/lib/ruleNames.js +5 -1
- package/lib/utilities/element.js +74 -12
- package/lib/utilities/json.js +2 -2
- package/lib/utilities/string.js +9 -24
- package/lib/utilities/substitutions.js +14 -22
- package/lib/utilities/validation.js +3 -3
- package/package.json +4 -4
- package/src/context/ephemeral.js +170 -50
- package/src/context/file/nominal.js +136 -141
- package/src/context/liminal.js +22 -34
- package/src/context/scoped.js +33 -74
- package/src/context.js +97 -46
- package/src/element/assertion/contained.js +4 -0
- package/src/element/assertion/defined.js +6 -2
- package/src/element/assertion/property.js +15 -26
- package/src/element/assertion/satisfies.js +4 -0
- package/src/element/assertion/subproof.js +4 -0
- package/src/element/assertion/type.js +69 -77
- package/src/element/assumption.js +48 -16
- package/src/element/constructor/bracketed.js +11 -12
- package/src/element/constructor.js +4 -4
- package/src/element/declaration/constructor.js +5 -1
- package/src/element/derivation.js +3 -5
- package/src/element/equality.js +109 -74
- package/src/element/equivalence.js +7 -7
- package/src/element/equivalences.js +7 -5
- package/src/element/frame.js +25 -25
- package/src/element/hypothesis.js +4 -6
- package/src/element/judgement.js +54 -24
- package/src/element/metaType.js +1 -1
- package/src/element/metavariable.js +16 -3
- package/src/element/propertyRelation.js +2 -2
- package/src/element/reference.js +12 -26
- package/src/element/rule.js +8 -10
- package/src/element/signature.js +4 -4
- package/src/element/statement.js +27 -30
- package/src/element/subDerivation.js +3 -5
- package/src/element/substitution/frame.js +1 -1
- package/src/element/substitution/reference.js +1 -1
- package/src/element/substitution/statement.js +1 -1
- package/src/element/substitution/term.js +4 -2
- package/src/element/substitution.js +60 -36
- package/src/element/term.js +24 -5
- package/src/element/topLevelAssertion.js +4 -6
- package/src/element/topLevelMetaAssertion.js +4 -6
- package/src/element/variable.js +2 -0
- package/src/process/assign.js +114 -37
- package/src/process/unify.js +2 -3
- package/src/process/validate.js +5 -5
- package/src/process/verify.js +1 -1
- package/src/ruleNames.js +1 -0
- package/src/utilities/element.js +83 -26
- package/src/utilities/json.js +1 -1
- package/src/utilities/string.js +7 -29
- package/src/utilities/substitutions.js +18 -29
- package/src/utilities/validation.js +2 -2
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
import elements from "../../elements";
|
|
4
3
|
import Assertion from "../assertion";
|
|
5
4
|
|
|
6
5
|
import { define } from "../../elements";
|
|
7
|
-
import {
|
|
6
|
+
import { variableAssignmentFromTypeAssertion } from "../../process/assign";
|
|
8
7
|
|
|
9
8
|
export default define(class TypeAssertion extends Assertion {
|
|
10
9
|
constructor(context, string, node, term, type) {
|
|
@@ -29,49 +28,57 @@ export default define(class TypeAssertion extends Assertion {
|
|
|
29
28
|
return typeAssertionNode;
|
|
30
29
|
}
|
|
31
30
|
|
|
32
|
-
|
|
33
|
-
let
|
|
31
|
+
validate(assignments, stated, context) {
|
|
32
|
+
let validates = false;
|
|
34
33
|
|
|
35
|
-
|
|
34
|
+
const typeAssertionString = this.getString(); ///
|
|
36
35
|
|
|
37
|
-
context.trace(`
|
|
36
|
+
context.trace(`Validating the '${typeAssertionString}' type assertion...`);
|
|
38
37
|
|
|
39
|
-
const
|
|
38
|
+
const valid = this.isValid();
|
|
40
39
|
|
|
41
|
-
if (
|
|
42
|
-
|
|
43
|
-
verifiesWhenDerived = false;
|
|
40
|
+
if (valid) {
|
|
41
|
+
validates = true;
|
|
44
42
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
verifiesWhenDerived = this.verifyWhenDerived(context);
|
|
49
|
-
}
|
|
43
|
+
context.debug(`...the '${typeAssertionString}' type assertion is already valid.`);
|
|
44
|
+
} else {
|
|
45
|
+
const typeValidates = this.validateType(context);
|
|
50
46
|
|
|
51
|
-
if (
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
47
|
+
if (typeValidates) {
|
|
48
|
+
let validatesWhenStated = false,
|
|
49
|
+
validatesWhenDerived = false;
|
|
50
|
+
|
|
51
|
+
if (stated) {
|
|
52
|
+
validatesWhenStated = this.validateWhenStated(assignments, context);
|
|
53
|
+
} else {
|
|
54
|
+
validatesWhenDerived = this.validateWhenDerived(context);
|
|
55
|
+
}
|
|
55
56
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
if (validatesWhenStated || validatesWhenDerived) {
|
|
58
|
+
validates = true;
|
|
59
|
+
}
|
|
59
60
|
}
|
|
60
|
-
}
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
if (validates) {
|
|
63
|
+
const assertion = this; ///
|
|
64
|
+
|
|
65
|
+
context.addAssertion(assertion);
|
|
66
|
+
|
|
67
|
+
this.assign(assignments, stated, context);
|
|
68
|
+
|
|
69
|
+
context.debug(`...verified the '${typeAssertionString}' type assertion.`);
|
|
70
|
+
}
|
|
64
71
|
}
|
|
65
72
|
|
|
66
|
-
return
|
|
73
|
+
return validates;
|
|
67
74
|
}
|
|
68
75
|
|
|
69
|
-
|
|
70
|
-
let
|
|
76
|
+
validateType(context) {
|
|
77
|
+
let typeValidates;
|
|
71
78
|
|
|
72
79
|
const typeString = this.type.getString();
|
|
73
80
|
|
|
74
|
-
context.trace(`
|
|
81
|
+
context.trace(`Validating the '${typeString}' type...`);
|
|
75
82
|
|
|
76
83
|
const nominalTypeName = this.type.getNominalTypeName(),
|
|
77
84
|
type = context.findTypeByNominalTypeName(nominalTypeName);
|
|
@@ -79,58 +86,58 @@ export default define(class TypeAssertion extends Assertion {
|
|
|
79
86
|
if (type !== null) {
|
|
80
87
|
this.type = type;
|
|
81
88
|
|
|
82
|
-
|
|
89
|
+
typeValidates = true;
|
|
83
90
|
} else {
|
|
84
91
|
context.debug(`The '${typeString}' type is not present.`);
|
|
85
92
|
}
|
|
86
93
|
|
|
87
|
-
if (
|
|
94
|
+
if (typeValidates) {
|
|
88
95
|
context.debug(`...verified the '${typeString}' type.`);
|
|
89
96
|
}
|
|
90
97
|
|
|
91
|
-
return
|
|
98
|
+
return typeValidates;
|
|
92
99
|
}
|
|
93
100
|
|
|
94
|
-
|
|
95
|
-
let
|
|
101
|
+
validateWhenStated(assignments, context) {
|
|
102
|
+
let validatesWhenStated = false;
|
|
96
103
|
|
|
97
104
|
const typeAssertionString = this.getString(); ///
|
|
98
105
|
|
|
99
|
-
context.trace(`
|
|
106
|
+
context.trace(`Validating the '${typeAssertionString}' stated type assertion...`);
|
|
100
107
|
|
|
101
|
-
const
|
|
102
|
-
let
|
|
108
|
+
const termValidates = this.term.validate(context, () => {
|
|
109
|
+
let validatesForwards;
|
|
103
110
|
|
|
104
111
|
const termType = this.term.getType(),
|
|
105
112
|
typeEqualToOrSubTypeOfTermType = this.type.isEqualToOrSubTypeOf(termType);
|
|
106
113
|
|
|
107
114
|
if (typeEqualToOrSubTypeOfTermType) {
|
|
108
|
-
|
|
115
|
+
validatesForwards = true;
|
|
109
116
|
}
|
|
110
117
|
|
|
111
|
-
return
|
|
118
|
+
return validatesForwards;
|
|
112
119
|
});
|
|
113
120
|
|
|
114
|
-
if (
|
|
115
|
-
|
|
121
|
+
if (termValidates) {
|
|
122
|
+
validatesWhenStated = true;
|
|
116
123
|
}
|
|
117
124
|
|
|
118
|
-
if (
|
|
125
|
+
if (validatesWhenStated) {
|
|
119
126
|
context.debug(`...verified the '${typeAssertionString}' stated type assertion.`);
|
|
120
127
|
}
|
|
121
128
|
|
|
122
|
-
return
|
|
129
|
+
return validatesWhenStated;
|
|
123
130
|
}
|
|
124
131
|
|
|
125
|
-
|
|
126
|
-
let
|
|
132
|
+
validateWhenDerived(context) {
|
|
133
|
+
let validatesWhenDerived;
|
|
127
134
|
|
|
128
135
|
const typeAssertionString = this.getString(); ///
|
|
129
136
|
|
|
130
|
-
context.trace(`
|
|
137
|
+
context.trace(`Validating the '${typeAssertionString}' derived type assertion...`);
|
|
131
138
|
|
|
132
|
-
const
|
|
133
|
-
let
|
|
139
|
+
const termValidates = this.term.validate(context, () => {
|
|
140
|
+
let validatesForwards = false;
|
|
134
141
|
|
|
135
142
|
const termType = this.term.getType(),
|
|
136
143
|
termTypeProvisional = termType.isProvisional();
|
|
@@ -138,52 +145,37 @@ export default define(class TypeAssertion extends Assertion {
|
|
|
138
145
|
if (!termTypeProvisional) {
|
|
139
146
|
const typeEqualToOrSuperTypeOfTermType = this.type.isEqualToOrSuperTypeOf(termType);
|
|
140
147
|
|
|
141
|
-
|
|
148
|
+
if (typeEqualToOrSuperTypeOfTermType) {
|
|
149
|
+
validatesForwards = true;
|
|
150
|
+
}
|
|
142
151
|
}
|
|
143
152
|
|
|
144
|
-
return
|
|
153
|
+
return validatesForwards;
|
|
145
154
|
});
|
|
146
155
|
|
|
147
|
-
|
|
156
|
+
validatesWhenDerived = termValidates; ///
|
|
148
157
|
|
|
149
|
-
if (
|
|
158
|
+
if (validatesWhenDerived) {
|
|
150
159
|
context.debug(`...verified the '${typeAssertionString}' derived type assertion.`);
|
|
151
160
|
}
|
|
152
161
|
|
|
153
|
-
return
|
|
162
|
+
return validatesWhenDerived;
|
|
154
163
|
}
|
|
155
164
|
|
|
156
|
-
assign(assignments, context) {
|
|
165
|
+
assign(assignments, stated, context) {
|
|
157
166
|
if (assignments === null) {
|
|
158
167
|
return;
|
|
159
168
|
}
|
|
160
169
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
let type,
|
|
165
|
-
provisional;
|
|
166
|
-
|
|
167
|
-
provisional = this.type.isProvisional();
|
|
168
|
-
|
|
169
|
-
if (!provisional) {
|
|
170
|
-
type = this.type;
|
|
171
|
-
} else {
|
|
172
|
-
provisional = false;
|
|
173
|
-
|
|
174
|
-
type = Type.fromTypeAndProvisional(this.type, provisional);
|
|
170
|
+
if (!stated) {
|
|
171
|
+
return;
|
|
175
172
|
}
|
|
176
173
|
|
|
177
|
-
const
|
|
174
|
+
const typeAssertion = this, ///
|
|
175
|
+
variableAssigment = variableAssignmentFromTypeAssertion(typeAssertion, context),
|
|
176
|
+
assignment = variableAssigment; ///
|
|
178
177
|
|
|
179
|
-
|
|
180
|
-
const variableNode = singularVariableNode, ///
|
|
181
|
-
variable = Variable.fromVariableNodeAndType(variableNode, type, context),
|
|
182
|
-
variableAssignment = variableAssignmentFromVariable(variable),
|
|
183
|
-
assignment = variableAssignment; ///
|
|
184
|
-
|
|
185
|
-
assignments.push(assignment);
|
|
186
|
-
}
|
|
178
|
+
assignments.push(assignment);
|
|
187
179
|
}
|
|
188
180
|
|
|
189
181
|
static name = "TypeAssertion";
|
|
@@ -31,6 +31,18 @@ export default define(class Assumption extends Element {
|
|
|
31
31
|
|
|
32
32
|
getMetavariable() { return this.reference.getMetavariable(); }
|
|
33
33
|
|
|
34
|
+
matchAssumptionNode(assumptionode) {
|
|
35
|
+
const assumptionodeA = assumptionode; ///
|
|
36
|
+
|
|
37
|
+
assumptionode = this.getAssumptionNode();
|
|
38
|
+
|
|
39
|
+
const assumptionodeB = assumptionode, ///
|
|
40
|
+
assumptionodeAAMatchesAssumptionBNodeB = assumptionodeA.match(assumptionodeB),
|
|
41
|
+
assumptionodeMatches = assumptionodeAAMatchesAssumptionBNodeB; ///
|
|
42
|
+
|
|
43
|
+
return assumptionodeMatches;
|
|
44
|
+
}
|
|
45
|
+
|
|
34
46
|
compareSubstitution(substitution, context) {
|
|
35
47
|
let comparesToSubstituion = false;
|
|
36
48
|
|
|
@@ -55,6 +67,14 @@ export default define(class Assumption extends Element {
|
|
|
55
67
|
return comparesToSubstituion;
|
|
56
68
|
}
|
|
57
69
|
|
|
70
|
+
isValid(context) {
|
|
71
|
+
const assumptionNode = this.getAssumptionNode(),
|
|
72
|
+
assumptionPresent = context.isAssumptionPresentByAssumptionNode(assumptionNode),
|
|
73
|
+
valid = assumptionPresent; ///
|
|
74
|
+
|
|
75
|
+
return valid;
|
|
76
|
+
}
|
|
77
|
+
|
|
58
78
|
validate(assignments, stated, context) {
|
|
59
79
|
let validates = false;
|
|
60
80
|
|
|
@@ -62,29 +82,41 @@ export default define(class Assumption extends Element {
|
|
|
62
82
|
|
|
63
83
|
context.trace(`Validating the '${assumptionString}' assumption...`);
|
|
64
84
|
|
|
65
|
-
const
|
|
85
|
+
const valid = this.isValid(context);
|
|
66
86
|
|
|
67
|
-
if (
|
|
68
|
-
|
|
87
|
+
if (valid) {
|
|
88
|
+
validates = true;
|
|
69
89
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
90
|
+
context.debug(`...the '${assumptionString}' assumption is already valid.`);
|
|
91
|
+
} else {
|
|
92
|
+
const referenceValidates = this.validateReference(assignments, stated, context);
|
|
73
93
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
94
|
+
if (referenceValidates) {
|
|
95
|
+
const statementValidates = this.validateStatement(assignments, stated, context);
|
|
96
|
+
|
|
97
|
+
if (statementValidates) {
|
|
98
|
+
let validatesWhenStated = false,
|
|
99
|
+
validatesWhenDerived = false;
|
|
100
|
+
|
|
101
|
+
if (stated) {
|
|
102
|
+
validatesWhenStated = this.validateWhenStated(assignments, context);
|
|
103
|
+
} else {
|
|
104
|
+
validatesWhenDerived = this.validateWhenDerived(context);
|
|
105
|
+
}
|
|
79
106
|
|
|
80
|
-
|
|
81
|
-
|
|
107
|
+
if (validatesWhenStated || validatesWhenDerived) {
|
|
108
|
+
validates = true;
|
|
109
|
+
}
|
|
82
110
|
}
|
|
83
111
|
}
|
|
84
|
-
}
|
|
85
112
|
|
|
86
|
-
|
|
87
|
-
|
|
113
|
+
if (validates) {
|
|
114
|
+
const assumption = this; ///
|
|
115
|
+
|
|
116
|
+
context.addAssumption(assumption);
|
|
117
|
+
|
|
118
|
+
context.debug(`...validated the '${assumptionString}' assumption.`);
|
|
119
|
+
}
|
|
88
120
|
}
|
|
89
121
|
|
|
90
122
|
return validates;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
import elements from "../../elements";
|
|
4
3
|
import Constructor from "../constructor";
|
|
5
4
|
|
|
6
5
|
import { define } from "../../elements";
|
|
6
|
+
import { termFromTermNode } from "../../utilities/element";
|
|
7
7
|
|
|
8
8
|
export default define(class BracketedConstructor extends Constructor {
|
|
9
9
|
getBracketedConstructorNode() {
|
|
@@ -13,7 +13,7 @@ export default define(class BracketedConstructor extends Constructor {
|
|
|
13
13
|
return bracketedConstructorNode;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
unifyTerm(term, context,
|
|
16
|
+
unifyTerm(term, context, validateForwards) {
|
|
17
17
|
let termUnifies;
|
|
18
18
|
|
|
19
19
|
const termString = term.getString();
|
|
@@ -21,34 +21,33 @@ export default define(class BracketedConstructor extends Constructor {
|
|
|
21
21
|
context.trace(`Unifying the '${termString}' term with the bracketed constructor...`);
|
|
22
22
|
|
|
23
23
|
termUnifies = super.unifyTerm(term, context, () => {
|
|
24
|
-
let
|
|
24
|
+
let validatesForwards = false;
|
|
25
25
|
|
|
26
|
-
const
|
|
27
|
-
bracketedTerm = term, ///
|
|
26
|
+
const bracketedTerm = term, ///
|
|
28
27
|
bracketedTermNode = bracketedTerm.getNode(),
|
|
29
28
|
singularTermNode = bracketedTermNode.getSingularTermNode();
|
|
30
29
|
|
|
31
30
|
if (singularTermNode !== null) {
|
|
32
31
|
const termNode = singularTermNode; ///
|
|
33
32
|
|
|
34
|
-
term =
|
|
33
|
+
term = termFromTermNode(termNode, context);
|
|
35
34
|
|
|
36
|
-
const
|
|
37
|
-
let
|
|
35
|
+
const termValidates = term.validate(context, () => {
|
|
36
|
+
let validatesForwards;
|
|
38
37
|
|
|
39
38
|
const type = term.getType();
|
|
40
39
|
|
|
41
40
|
bracketedTerm.setType(type);
|
|
42
41
|
|
|
43
|
-
|
|
42
|
+
validatesForwards = validateForwards();
|
|
44
43
|
|
|
45
|
-
return
|
|
44
|
+
return validatesForwards;
|
|
46
45
|
});
|
|
47
46
|
|
|
48
|
-
|
|
47
|
+
validatesForwards = termValidates; ///
|
|
49
48
|
}
|
|
50
49
|
|
|
51
|
-
return
|
|
50
|
+
return validatesForwards;
|
|
52
51
|
});
|
|
53
52
|
|
|
54
53
|
if (termUnifies) {
|
|
@@ -30,7 +30,7 @@ export default define(class Constructor extends Element {
|
|
|
30
30
|
|
|
31
31
|
setType(type) { this.term.setType(type); }
|
|
32
32
|
|
|
33
|
-
unifyTerm(term, context,
|
|
33
|
+
unifyTerm(term, context, validateForwards) {
|
|
34
34
|
let termUnifies = false;
|
|
35
35
|
|
|
36
36
|
const termString = term.getString(),
|
|
@@ -42,15 +42,15 @@ export default define(class Constructor extends Element {
|
|
|
42
42
|
termUnifiesWithConstructor = unifyTermWithConstructor(term, constructor, context);
|
|
43
43
|
|
|
44
44
|
if (termUnifiesWithConstructor) {
|
|
45
|
-
let
|
|
45
|
+
let validatesForwards;
|
|
46
46
|
|
|
47
47
|
const type = this.getType();
|
|
48
48
|
|
|
49
49
|
term.setType(type);
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
validatesForwards = validateForwards();
|
|
52
52
|
|
|
53
|
-
termUnifies =
|
|
53
|
+
termUnifies = validatesForwards; ///
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
if (termUnifies) {
|
|
@@ -33,7 +33,11 @@ export default define(class ConstructorDeclaration extends Declaration {
|
|
|
33
33
|
|
|
34
34
|
const term = this.constructor.getTerm(),
|
|
35
35
|
termNode = term.getNode(),
|
|
36
|
-
termValidates = validateTerm(termNode, context)
|
|
36
|
+
termValidates = validateTerm(termNode, context, () => {
|
|
37
|
+
const validatesFormards = true;
|
|
38
|
+
|
|
39
|
+
return validatesFormards;
|
|
40
|
+
});
|
|
37
41
|
|
|
38
42
|
if (termValidates) {
|
|
39
43
|
constructorValidates = true;
|
|
@@ -43,13 +43,11 @@ export default define(class Derivation extends Element {
|
|
|
43
43
|
subproofOrProofAssertionVerifies = await subproofOrProofAssertion.verify(assignments, context);
|
|
44
44
|
|
|
45
45
|
if (subproofOrProofAssertionVerifies) {
|
|
46
|
-
|
|
46
|
+
assignAssignments(assignments, context);
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
context.addSubproofOrProofAssertion(subproofOrProofAssertion);
|
|
48
|
+
context.addSubproofOrProofAssertion(subproofOrProofAssertion);
|
|
50
49
|
|
|
51
|
-
|
|
52
|
-
}
|
|
50
|
+
return true;
|
|
53
51
|
}
|
|
54
52
|
});
|
|
55
53
|
|