map rules object on results run
This commit is contained in:
parent
98864740ca
commit
1e15578aec
2 changed files with 121 additions and 17 deletions
|
@ -1,11 +1,22 @@
|
||||||
// @flow
|
// @flow
|
||||||
import type { stateType } from './stateReducer';
|
import type { stateType, epochType, phoneType } from './stateReducer';
|
||||||
|
|
||||||
export type resultsAction = {
|
export type resultsAction = {
|
||||||
type: 'RUN'
|
type: 'RUN'
|
||||||
}
|
}
|
||||||
|
|
||||||
const findFeatures = (phones: {}, lexeme:string): [] => {
|
export type decomposedRulesType = [
|
||||||
|
{
|
||||||
|
environment: {
|
||||||
|
pre: [{[key: string]: boolean}],
|
||||||
|
position: [{[key: string]: boolean}],
|
||||||
|
post: [{[key: string]: boolean}]
|
||||||
|
},
|
||||||
|
newFeatures: [{[key: string]: boolean}]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const findFeaturesFromLexeme = (phones: {}, lexeme:string): [] => {
|
||||||
let featureBundle = []
|
let featureBundle = []
|
||||||
let lastIndex = lexeme.length - 1;
|
let lastIndex = lexeme.length - 1;
|
||||||
let node = {};
|
let node = {};
|
||||||
|
@ -23,12 +34,80 @@ const findFeatures = (phones: {}, lexeme:string): [] => {
|
||||||
})
|
})
|
||||||
return featureBundle;
|
return featureBundle;
|
||||||
}
|
}
|
||||||
|
const findFeaturesFromGrapheme = (phones: {}, lexeme:string): [] => {
|
||||||
|
let featureBundle = []
|
||||||
|
let lastIndex = lexeme.length - 1;
|
||||||
|
let node = {};
|
||||||
|
[...lexeme].forEach((graph, index) => {
|
||||||
|
if (!index && !lastIndex) featureBundle.push(phones[graph].features)
|
||||||
|
if (!index) return node = phones[graph]
|
||||||
|
if (index === lastIndex) return node[graph]
|
||||||
|
? featureBundle.push(node[graph])
|
||||||
|
: featureBundle.push(node, phones[graph])
|
||||||
|
if (!node[graph] && node.features) {
|
||||||
|
featureBundle.push(node)
|
||||||
|
return node = phones[graph]
|
||||||
|
}
|
||||||
|
if (!node[graph])
|
||||||
|
return node = node[graph]
|
||||||
|
})
|
||||||
|
return featureBundle;
|
||||||
|
}
|
||||||
|
|
||||||
const decomposeRule = (rule: string): string[] => {
|
const decomposeRule = (rule: string) => {
|
||||||
let decomposedChange = rule.split('>');
|
let decomposedChange = rule.split('>');
|
||||||
decomposedChange = [decomposedChange[0], ...decomposedChange[1].split('/')]
|
decomposedChange = [decomposedChange[0], ...decomposedChange[1].split('/')]
|
||||||
decomposedChange = [decomposedChange[0], decomposedChange[1], ...decomposedChange[2].split('_')];
|
decomposedChange = [decomposedChange[0], decomposedChange[1], ...decomposedChange[2].split('_')];
|
||||||
return [...decomposedChange];
|
const ruleBundle = {
|
||||||
|
environment: {
|
||||||
|
pre: decomposedChange[2],
|
||||||
|
position: decomposedChange[0],
|
||||||
|
post: decomposedChange[3]
|
||||||
|
},
|
||||||
|
newFeatures: decomposedChange[1]
|
||||||
|
}
|
||||||
|
return ruleBundle;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapStringToFeatures = (ruleString, phones) => {
|
||||||
|
if (ruleString) {
|
||||||
|
const ruleBrackets = ruleString.match(/\[.*\]/)
|
||||||
|
if (ruleBrackets) {
|
||||||
|
const ruleFeatures = ruleString.match(/(?!\[).*(?<!\])/)[0]
|
||||||
|
const plusIndex = ruleFeatures.indexOf('+');
|
||||||
|
const minusIndex = ruleFeatures.indexOf('-');
|
||||||
|
const positiveFeatures = ruleFeatures.slice(plusIndex + 1, minusIndex).trim().split(' ');
|
||||||
|
const positiveFeaturesMap = positiveFeatures.map(feature => ({[feature]: true}))
|
||||||
|
const negativeFeatures = ruleFeatures.slice(minusIndex +1).trim().split(' ');
|
||||||
|
const negativeFeaturesMap = negativeFeatures.map(feature => ({[feature]: false}))
|
||||||
|
return {...positiveFeaturesMap, ...negativeFeaturesMap}
|
||||||
|
}
|
||||||
|
const grapheme = ruleString;
|
||||||
|
return findFeaturesFromGrapheme(phones, grapheme);
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapRuleBundleToFeatureBundle = (ruleBundle, phones) => {
|
||||||
|
// ! for each object in ruleBundle, map values to array of objects with feature-boolean key-value pairs
|
||||||
|
const featureBundle = {...ruleBundle};
|
||||||
|
console.log(featureBundle)
|
||||||
|
featureBundle.environment.pre = mapStringToFeatures(featureBundle.environment.pre, phones);
|
||||||
|
console.log(featureBundle.environment.pre)
|
||||||
|
featureBundle.environment.position = mapStringToFeatures(featureBundle.environment.position, phones);
|
||||||
|
console.log(featureBundle.environment.position)
|
||||||
|
featureBundle.environment.post = mapStringToFeatures(featureBundle.environment.post, phones);
|
||||||
|
console.log(featureBundle.environment.post)
|
||||||
|
featureBundle.newFeatures = mapStringToFeatures(featureBundle.newFeatures, phones);
|
||||||
|
console.log(featureBundle.newFeatures)
|
||||||
|
return featureBundle;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const decomposeRules = (epoch: epochType, phones: {[key: string]: phoneType}): decomposedRulesType => {
|
||||||
|
let ruleBundle = [...epoch.changes]
|
||||||
|
ruleBundle = epoch.changes.map(rule => decomposeRule(rule));
|
||||||
|
const featureBundle = ruleBundle.map(rule => mapRuleBundleToFeatureBundle(rule, phones));
|
||||||
|
return featureBundle;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const run = (state: stateType, action: resultsAction): stateType => {
|
export const run = (state: stateType, action: resultsAction): stateType => {
|
||||||
|
@ -43,7 +122,7 @@ export const run = (state: stateType, action: resultsAction): stateType => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
let featurePhoneBundle = state.lexicon.map(lexeme => findFeatures(state.phones, lexeme))
|
let featurePhoneBundle = state.lexicon.map(lexeme => findFeaturesFromLexeme(state.phones, lexeme))
|
||||||
|
|
||||||
console.log(featurePhoneBundle)
|
console.log(featurePhoneBundle)
|
||||||
ruleBundle.forEach(rule => {
|
ruleBundle.forEach(rule => {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { stateReducer } from './stateReducer';
|
import { stateReducer } from './stateReducer';
|
||||||
import { initState } from './stateReducer.init';
|
import { initState } from './stateReducer.init';
|
||||||
|
import { decomposeRules } from './stateReducer.results';
|
||||||
|
|
||||||
describe('Results', () => {
|
describe('Results', () => {
|
||||||
let state = {};
|
let state = {};
|
||||||
|
@ -12,15 +13,39 @@ describe('Results', () => {
|
||||||
expect(stateReducer(state, action)).toBe(state);
|
expect(stateReducer(state, action)).toBe(state);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('results returned from first sound change rule', () => {
|
it('rules decomposed properly', () => {
|
||||||
const action = {type: 'RUN'};
|
const epoch = initState().epochs[0];
|
||||||
state = initState(0)
|
epoch.changes = epoch.changes.slice(0,1)
|
||||||
expect(stateReducer(state, action).results).toEqual({
|
const phones = initState().phones;
|
||||||
pass: 'epoch 1',
|
const result = [
|
||||||
results: [
|
{
|
||||||
'anna', 'anat', 'anət', 'anna', 'tan', 'ənna'
|
// ! '[+ occlusive - nasal]>[+ occlusive nasal]/n_',
|
||||||
]
|
environment: {
|
||||||
|
pre: [
|
||||||
|
{
|
||||||
|
sonorant: true, nasal: true, occlusive: true, coronal: true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
position: [
|
||||||
|
{occlusive: true, nasal: false}
|
||||||
|
],
|
||||||
|
post: [],
|
||||||
|
},
|
||||||
|
newFeatures: {occlusive: true, nasal: true}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
expect(decomposeRules(epoch, phones)).toBe(result);
|
||||||
})
|
})
|
||||||
});
|
|
||||||
|
// it('results returned from first sound change rule', () => {
|
||||||
|
// const action = {type: 'RUN'};
|
||||||
|
// state = initState(0)
|
||||||
|
// expect(stateReducer(state, action).results).toEqual({
|
||||||
|
// pass: 'epoch 1',
|
||||||
|
// results: [
|
||||||
|
// 'anna', 'anat', 'anət', 'anna', 'tan', 'ənna'
|
||||||
|
// ]
|
||||||
|
// })
|
||||||
|
// });
|
||||||
|
|
||||||
});
|
});
|
Loading…
Reference in a new issue