Skip to content

Commit

Permalink
Merge pull request #366 from karlfloersch/feat/335/add_simple_quantif…
Browse files Browse the repository at this point in the history
…iers

Add integer quantifiers
  • Loading branch information
karlfloersch committed Jul 25, 2019
2 parents 56a933a + e3e2bf8 commit 87dfb1b
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/core/src/app/ovm/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './state-db'
export * from './state-manager'
export * from './integer-quantifiers'
71 changes: 71 additions & 0 deletions packages/core/src/app/ovm/integer-quantifiers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { QuantifierResult, Quantifier } from '../../types'

// Helper function which returns an array of numbers, starting at start, ending at end, incrementing by 1.
// Eg. [0, 1, 2,...end]
const range = (start: number, end: number): number[] => {
return Array(end - start)
.fill(start)
.map((x, y) => x + y)
}

/*
* The parameter type for `getAllQuantified(...)` in the IntegerRangeQuantifier.
*/
interface IntegerRangeParameters {
start: number
end: number
}

/*
* The IntegerRangeQuantifier returns a range of integers between the start (inclusive) & end (exclusive).
*/
export class IntegerRangeQuantifier implements Quantifier {
/**
* Returns a QuantifierResult where results are an array of integers from 0 to withinThisRange. Eg. 3 to 6 = [3, 4, 5]
* and `allResultsQuantified` is set to `true`--this is because we always can quantify integers in this range.
*
* @param withinThisRange the range of the integers we would like to return.
*/
public getAllQuantified(withinThisRange: {
start: number
end: number
}): QuantifierResult {
if (withinThisRange.end < withinThisRange.start) {
throw new Error('Invalid quantifier input! End is less than the start.')
}
return {
results: range(withinThisRange.start, withinThisRange.end),
allResultsQuantified: true,
}
}
}

/*
* The parameter type for `getAllQuantified(...)` in the NonnegativeIntegerLessThanQuantifier
*/
type NonnegativeIntegerLessThanQuantifierParameters = number

/*
* The NonnegativeIntegerLessThanQuantifier returns all non-negative integers less than the specified number
*/
export class NonnegativeIntegerLessThanQuantifier implements Quantifier {
/**
* Returns a QuantifierResult where results are an array of integers from 0 to lessThanThis. Eg. 0 to 3 = [0, 1, 2]
* and `allResultsQuantified` is set to `true`--this is because we always can quantify integers in this range.
*
* @param lessThanThis the upper bound for the array. Note this is non-inclusive.
*/
public getAllQuantified(
lessThanThis: NonnegativeIntegerLessThanQuantifierParameters
): QuantifierResult {
if (lessThanThis < 0) {
throw new Error(
'Invalid quantifier input! Cannot quantify negative number.'
)
}
return {
results: range(0, lessThanThis),
allResultsQuantified: true,
}
}
}
1 change: 1 addition & 0 deletions packages/core/src/types/ovm/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from './state-db.interface'
export * from './predicate-plugin.interface'
export * from './plugin-manager.interface'
export * from './sync-manager'
export * from './quantifier.interface'
91 changes: 91 additions & 0 deletions packages/core/test/app/ovm/integer-quantifiers.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/* Internal Imports */
import {
IntegerRangeQuantifier,
NonnegativeIntegerLessThanQuantifier,
} from '../../../src/app'

describe('IntegerQuantifiers', () => {
describe('IntegerRangeQuantifier', () => {
it('should quantify a positive range', async () => {
const quantifier = new IntegerRangeQuantifier()
const range = quantifier.getAllQuantified({ start: 100, end: 105 })
range.should.deep.equal({
results: [100, 101, 102, 103, 104],
allResultsQuantified: true,
})
})

it('should quantify a large positive range', async () => {
const quantifier = new IntegerRangeQuantifier()
const range = quantifier.getAllQuantified({ start: 100, end: 1005 })
// Generate a range from 100 to 1005
const expectedResult = []
for (let i = 100; i < 1005; i++) {
expectedResult.push(i)
}
range.should.deep.equal({
results: expectedResult,
allResultsQuantified: true,
})
})

it('should quantify a negative range', async () => {
const quantifier = new IntegerRangeQuantifier()
const range = quantifier.getAllQuantified({ start: -105, end: -100 })
range.should.deep.equal({
results: [-105, -104, -103, -102, -101],
allResultsQuantified: true,
})
})

it('should quantify a range with a negative start & positive end', async () => {
const quantifier = new IntegerRangeQuantifier()
const range = quantifier.getAllQuantified({ start: -3, end: 2 })
range.should.deep.equal({
results: [-3, -2, -1, 0, 1],
allResultsQuantified: true,
})
})

it('should throw an error if end < start ', async () => {
const quantifier = new IntegerRangeQuantifier()
const callGetQuantified = () =>
quantifier.getAllQuantified({ start: 100, end: 95 })
callGetQuantified.should.throw()
})

it('should return an empty array if start == end', async () => {
const quantifier = new IntegerRangeQuantifier()
const range = quantifier.getAllQuantified({ start: 100, end: 100 })
range.should.deep.equal({
results: [],
allResultsQuantified: true,
})
})
})
describe('NonnegativeIntegerLessThanQuantifier', () => {
it('should quantify numbers less than 5', async () => {
const quantifier = new NonnegativeIntegerLessThanQuantifier()
const range = quantifier.getAllQuantified(5)
range.should.deep.equal({
results: [0, 1, 2, 3, 4],
allResultsQuantified: true,
})
})

it('should throw an error if attempting to quantify nonnegative numbers less than 0', async () => {
const quantifier = new NonnegativeIntegerLessThanQuantifier()
const callGetQuantified = () => quantifier.getAllQuantified(-5)
callGetQuantified.should.throw()
})

it('should return an empty array if quantifying `less than 0`', async () => {
const quantifier = new NonnegativeIntegerLessThanQuantifier()
const range = quantifier.getAllQuantified(0)
range.should.deep.equal({
results: [],
allResultsQuantified: true,
})
})
})
})

0 comments on commit 87dfb1b

Please sign in to comment.