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
|
||||
import type { stateType } from './stateReducer';
|
||||
import type { stateType, epochType, phoneType } from './stateReducer';
|
||||
|
||||
export type resultsAction = {
|
||||
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 lastIndex = lexeme.length - 1;
|
||||
let node = {};
|
||||
|
@ -23,12 +34,80 @@ const findFeatures = (phones: {}, lexeme:string): [] => {
|
|||
})
|
||||
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('>');
|
||||
decomposedChange = [decomposedChange[0], ...decomposedChange[1].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 => {
|
||||
|
@ -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)
|
||||
ruleBundle.forEach(rule => {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import {stateReducer} from './stateReducer';
|
||||
import {initState} from './stateReducer.init';
|
||||
import { stateReducer } from './stateReducer';
|
||||
import { initState } from './stateReducer.init';
|
||||
import { decomposeRules } from './stateReducer.results';
|
||||
|
||||
describe('Results', () => {
|
||||
let state = {};
|
||||
|
@ -12,15 +13,39 @@ describe('Results', () => {
|
|||
expect(stateReducer(state, action)).toBe(state);
|
||||
});
|
||||
|
||||
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'
|
||||
]
|
||||
})
|
||||
});
|
||||
it('rules decomposed properly', () => {
|
||||
const epoch = initState().epochs[0];
|
||||
epoch.changes = epoch.changes.slice(0,1)
|
||||
const phones = initState().phones;
|
||||
const result = [
|
||||
{
|
||||
// ! '[+ 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