From 31fab0ea57317b3fe2e767bb9fb25be0616168a1 Mon Sep 17 00:00:00 2001 From: Sorrel Bri Date: Fri, 21 Feb 2020 15:17:59 -0800 Subject: [PATCH] add support for multiple epochs with dependencies --- src/reducers/reducer.results.js | 41 +++++++++++------- src/reducers/reducer.results.test.js | 63 +++++++++++++++++++++++++--- 2 files changed, 84 insertions(+), 20 deletions(-) diff --git a/src/reducers/reducer.results.js b/src/reducers/reducer.results.js index 03b631a..5fd3909 100644 --- a/src/reducers/reducer.results.js +++ b/src/reducers/reducer.results.js @@ -204,8 +204,10 @@ const transformPhoneme = (phoneme, newFeatures, features) => { const transformLexemeInitial = (newLexeme, pre, post, position, phoneme, index, lexemeBundle, newFeatures, features) => { if (index !== pre.length - 1) return [...newLexeme, phoneme]; if (!isEnvironmentBoundByRule([phoneme], position)) return [...newLexeme, phoneme]; - if (!isEnvironmentBoundByRule(lexemeBundle.slice(index, index + post.length), post)) return [...newLexeme, phoneme]; + if (!isEnvironmentBoundByRule(lexemeBundle.slice(index + position.length, index + post.length + position.length), post)) return [...newLexeme, phoneme]; const newPhoneme = transformPhoneme(phoneme, newFeatures[0], features); + // if deletion occurs + if (!newPhoneme.grapheme) return [ ...newLexeme] ; return [...newLexeme, newPhoneme]; } @@ -214,6 +216,8 @@ const transformLexemeCoda = (newLexeme, pre, post, position, phoneme, index, lex if (!isEnvironmentBoundByRule(lexemeBundle.slice(index - pre.length, index), pre)) return [...newLexeme, phoneme]; if (!isEnvironmentBoundByRule([phoneme], position)) return [...newLexeme, phoneme]; const newPhoneme = transformPhoneme(phoneme, newFeatures[0], features); + // if deletion occurs + if (!newPhoneme.grapheme) return [ ...newLexeme] ; return [...newLexeme, newPhoneme]; } @@ -245,26 +249,33 @@ const transformLexicon = lexiconBundle => )) const getGraphemeFromEntry = ([_, phoneme]) => phoneme.grapheme -const stringifyResults = lexemeBundle => Object.entries(lexemeBundle).map(getGraphemeFromEntry).join('') +const stringifyResults = passResults => { + const lexicon = passResults.lexicon.map(lexeme => lexeme.map(phoneme => phoneme.grapheme).join('')) + return {...passResults, lexicon } +} export const run = (state: stateType, action: resultsAction): stateType => { // TODO iterate through each epoch try { - const epoch = state.epochs[0]; - const { phones, lexicon, features } = state; - - const ruleBundle = decomposeRules(epoch, phones); - const lexiconBundle = formBundleFromLexicon(lexicon)(phones); - const passResults = transformLexicon(lexiconBundle)(ruleBundle)(features); - const stringifiedPassResults = passResults.map(stringifyResults); - const pass = { - pass: epoch.name, - lexicon: stringifiedPassResults - } - - return {...state, results: [pass] } + const passResults = state.epochs.reduce((results, epoch, _) => { + + const { phones, features } = state; + const lexicon = epoch.parent ? results.find(result => result.pass === epoch.parent).lexicon : state.lexicon + const ruleBundle = decomposeRules(epoch, phones); + const lexiconBundle = epoch.parent ? lexicon : formBundleFromLexicon(lexicon)(phones); + const passResults = transformLexicon(lexiconBundle)(ruleBundle)(features) + const pass = { + pass: epoch.name, + lexicon: passResults + } + if ( epoch.parent ) pass.parent = epoch.parent; + return [...results, pass]; + }, []); + const results = passResults.map(stringifyResults); + return {...state, results } } catch (err) { + console.log(err) return err; } } \ No newline at end of file diff --git a/src/reducers/reducer.results.test.js b/src/reducers/reducer.results.test.js index 69fdb77..2218080 100644 --- a/src/reducers/reducer.results.test.js +++ b/src/reducers/reducer.results.test.js @@ -134,20 +134,73 @@ describe('Results', () => { ]); }); + // it('results returned through sixth sound change rule (multi-phoneme target)', () => { + // const action = {type: 'RUN'}; + // state = initState(6) + // expect(stateReducer(state, action).results).toEqual([ + // { + // pass: 'epoch 1', + // lexicon: [ + // 'annu', 'anta', 'ant', 'annu', 'tʰan', 'nnu' + // ] + // } + // ]); + // }); - it('results returned through sixth sound change rule (multi-phoneme target)', () => { + it('results returned for multiple epochs without parent epoch', () => { const action = {type: 'RUN'}; - state = initState(5) + state = initState(5); + const newEpoch = { + name: 'epoch 2', + changes: [ + '[+ sonorant ]>0/#_.', + 'n>0/#_n' + ] + } + state.epochs = [ ...state.epochs, newEpoch ] expect(stateReducer(state, action).results).toEqual([ { pass: 'epoch 1', lexicon: [ - 'annu', 'anta', 'ant', 'annu', 'tʰan', 'nnu' + 'annu', 'anat', 'ant', 'annu', 'tʰan', 'nnu' + ] + }, + { + pass: 'epoch 2', + lexicon: [ + 'nta', 'nat', 'nət', 'na', 'tan', 'nta' ] } - ]); - }); + ]) + }) + it('results returned for multiple epochs with parent epoch', () => { + const action = {type: 'RUN'}; + state = initState(5); + const newEpoch = { + name: 'epoch 2', + parent: 'epoch 1', + changes: [ + '[+ sonorant ]>0/#_.' + ] + } + state.epochs = [ ...state.epochs, newEpoch ] + expect(stateReducer(state, action).results).toEqual([ + { + pass: 'epoch 1', + lexicon: [ + 'annu', 'anat', 'ant', 'annu', 'tʰan', 'nnu' + ] + }, + { + pass: 'epoch 2', + parent: 'epoch 1', + lexicon: [ + 'nnu', 'nat', 'nt', 'nnu', 'tʰan', 'nu' + ] + } + ]) + }) });