UNPKG

theprogrammablemind

Version:

155 lines (138 loc) 3.93 kB
const { isArray, isObject, isCompound } = require('./helpers') const _ = require('lodash') const DEBUG = (...args) => { // DEBUG(...args) } const flattens = (markers, contexts) => { let flats = [] for (const context of contexts) { // const [more, _] = flatten(markers, context) const more = flatten(markers, context)[0] flats = flats.concat(more) } return flats } const accumulate = (accumulator, nexts) => { const accumulatorPrime = [] for (const current of accumulator) { for (const next of nexts) { const nextCurrent = _.clone(current) nextCurrent.push(next) accumulatorPrime.push(nextCurrent) } } return accumulatorPrime } const cartesianHelper = (accumulator, b, ...c) => { if (b) { return cartesianHelper(accumulate(accumulator, b), ...c) } else { return accumulator } } const cartesian = (...factors) => { return cartesianHelper([[]], ...factors) } const zip = (a1, a2) => { return a1.map(function (value, index) { return [value, a2[index]] }) } const flattenListHelper = (markers, values) => { const flats = [] let wasFlattened = false let singles = [] for (const value of values) { if (!isCompound(value)) { singles.push(value) } else { const [more, wf] = flatten(markers, value) if (wf) { wasFlattened = wasFlattened || wf flats.push(more) } else { singles = singles.concat(more) } } } // product does weirdness with only choice if (!wasFlattened) { return [[singles], wasFlattened] } else { const results = [] for (const flat of cartesian(...flats)) { results.push(singles.concat(flat)) } return [results, wasFlattened] } } // returns (list, wasFlattened) const flatten = (markers, value) => { if (isArray(value)) { return flattenListHelper(markers, value) } if (value.flatten === false) { return [[value], false] } const marker = value.marker let properties = value // if you want to pull up conj properties fix this to do to the other part // split = marker in markers const split = markers.includes(marker) if (split) { if ('value' in properties) { flattenedValues = [] for (const v of properties.value) { if (v.flatten) { flattenedValues = flattenedValues.concat(flatten(markers, v)[0]) } else { flattenedValues.push(v) } } return [flattenedValues, true] } else { return [[value], false] } } const keys = [] const valuess = [] const unchanged = {} DEBUG('properties', JSON.stringify(properties, null, 2)) for (const key in properties) { let wf = false let values // if isinstance(properties[key], Context) { if (isObject(properties[key])) { const context = properties[key]; [values, wf] = flatten(markers, context) // } else if (isinstance(properties[key], list)) { } else if (isArray(properties[key])) { [values, wf] = flattenListHelper(markers, properties[key]) } else { values = [properties[key]] } if (wf) { keys.push(key) valuess.push(values) } else { unchanged[key] = values[0] } } const propertiess = [] DEBUG('-----------> valuess', JSON.stringify(valuess)) DEBUG('-----------> cartesian(valuess)', JSON.stringify(cartesian(valuess))) // for (let values of itertools.product(*valuess)) { const cp = cartesian(...valuess) DEBUG('-----------> cp', JSON.stringify(cp)) for (const values of cartesian(...valuess)) { // properties = copy.deepcopy(unchanged) properties = _.cloneDeep(unchanged) // for key, value in zip(keys, values) { for (const [key, value] of zip(keys, values)) { properties[key] = value } propertiess.push(properties) } return [propertiess, valuess.length > 0] } module.exports = { flattens, flatten, cartesian, accumulate }