@syntest/search
Version:
The common core of the SynTest Framework
121 lines • 4.32 kB
JavaScript
;
/*
* Copyright 2020-2021 Delft University of Technology and SynTest contributors
*
* This file is part of SynTest Framework - SynTest Core.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.BranchDistance = void 0;
class BranchDistance {
/**
* Calculate the branch distance
*
* @param opcode the opcode (the comparison operator)
* @param left the left values of the comparison (multiple execution traces)
* @param right the right values of the comparison (multiple execution traces)
* @param target the side of the branch you want to cover
*/
branchDistanceNumeric(opcode, left, right, target) {
let branchDistance;
// TODO the SGT and SLT opcodes are for signed numbers
// look here: https://docs.soliditylang.org/en/v0.5.5/assembly.html
// TODO other opcodes
// TODO move this to the solidity project and make an abstraction of this class
switch (opcode) {
case "EQ": {
branchDistance = target
? this.equalNumeric(left, right)
: this.notEqualNumeric(left, right);
break;
}
case "NEQ": {
branchDistance = target
? this.notEqualNumeric(left, right)
: this.equalNumeric(left, right);
break;
}
case "GT":
case "SGT": {
branchDistance = target
? this.greater(left, right)
: this.smallerEqual(left, right);
break;
}
case "LT":
case "SLT": {
branchDistance = target
? this.smaller(left, right)
: this.greaterEqual(left, right);
break;
}
}
return this.normalize(branchDistance);
}
normalize(x) {
return x / (x + 1);
}
equalNumeric(left, right) {
let minimum = Number.MAX_VALUE;
for (const [index, element] of left.entries()) {
minimum = Math.min(minimum, Math.abs(element - right[index]));
}
return minimum;
}
notEqualNumeric(left, right) {
let minimum = Number.MAX_VALUE;
for (const [index, element] of left.entries()) {
minimum = element == right[index] ? Math.min(minimum, 1) : 0;
}
return minimum;
}
greater(left, right) {
let minimum = Number.MAX_VALUE;
for (const [index, element] of left.entries()) {
minimum =
element > right[index]
? 0
: Math.min(minimum, right[index] - element + 1);
}
return minimum;
}
smallerEqual(left, right) {
let minimum = Number.MAX_VALUE;
for (const [index, element] of left.entries()) {
minimum =
element <= right[index] ? 0 : Math.min(minimum, element - right[index]);
}
return minimum;
}
greaterEqual(left, right) {
let minimum = Number.MAX_VALUE;
for (const [index, element] of left.entries()) {
minimum =
element >= right[index] ? 0 : Math.min(minimum, right[index] - element);
}
return minimum;
}
smaller(left, right) {
let minimum = Number.MAX_VALUE;
for (const [index, element] of left.entries()) {
minimum =
element < right[index]
? 0
: Math.min(minimum, element - right[index] + 1);
}
return minimum;
}
}
exports.BranchDistance = BranchDistance;
//# sourceMappingURL=BranchDistance.js.map