Exemple #1
0
        IAcceptWord JoinConcatUnion(IAcceptWord automat, JoinConcatUnionKind kind) {
            if (!(automat is PDA pda2))
                throw new System.NotSupportedException();
            if (kind != JoinConcatUnionKind.Join && !(automat is StatePDA))
                throw new System.NotSupportedException();
            if (this is StackPDA || automat is StackPDA)
                throw new System.NotImplementedException();
            // TODO: investigate more, State PDA is perfect Stack PDA seems complicated

            // TODO: what if A1 or A2 has a StackStartsymbol set, should it be transformed
            // to a transform or applied

            uint offsetA1 = 0; // first state of A2
            uint offsetA2 = this.StatesCount; // first state of A2
            if (kind == JoinConcatUnionKind.Union) {
                offsetA1 = 1;
                offsetA2++;
            }

            char[] inputAlphabet = this.Alphabet.Union(pda2.Alphabet).ToArray();
            char[] workAlphabet = this.WorkAlphabet.Union(pda2.WorkAlphabet).ToArray();

            var pdat = new PDATransform();

            uint startState;
            // Union: add new start state, with e to both starts
            if (kind == JoinConcatUnionKind.Union) {
                startState = 0;
                pdat.Add(0, null, null, null, this.StartState + offsetA1);
                pdat.AddM(0, null, null, null, pda2.StartState + offsetA2);
            } else
                startState = this.StartState;

            // add each D1 transform + offset of A1
            foreach (var item in this.Transforms)
                foreach (var val in item.Value)
                    pdat.AddM(item.Key.q + offsetA1, item.Key.ci, item.Key.cw, val.cw2, val.qNext + offsetA1);

            // add each D1 transform, + offset of A2
            foreach (var item in pda2.Transforms)
                foreach (var val in item.Value)
                    pdat.AddM(item.Key.q + offsetA2, item.Key.ci, item.Key.cw, val.cw2, val.qNext + offsetA2);


            uint[] accStates;
            if (kind == JoinConcatUnionKind.Concat)
                // Concat: has only accepted states from A2
                accStates = new uint[pda2.AcceptedStates.Length];
            else
                // Join, Union has A1, A2 accpted states
                accStates = new uint[this.AcceptedStates.Length + pda2.AcceptedStates.Length];

            int i = 0; // store where D1 acc ends
            // iterate A1 acc
            for (; i < this.AcceptedStates.Length; i++)
                if (kind == JoinConcatUnionKind.Concat)
                    // Concat: lead accepted states from A1 to A2 start
                    pdat.AddM(this.AcceptedStates[i] + offsetA1, null, null, null, pda2.StartState + offsetA2);
                else
                    // Join, Union: states from A1 are normal accepted
                    accStates[i] = this.AcceptedStates[i] + offsetA1;

            if (kind == JoinConcatUnionKind.Concat)
                i = 0;

            // iterate A2 acs and + offsetA2
            for (int j = 0; j < pda2.AcceptedStates.Length; j++)
                accStates[i + j] = (pda2.AcceptedStates[j] + offsetA2);

            if (this is StatePDA)
                return new StatePDA($"{kind.ToString()}({Name}+{pda2.Name})", this.StatesCount + pda2.StatesCount + offsetA1, inputAlphabet, workAlphabet, pdat, startState, pda2.StartSymbol, accStates);
            else if (this is StackPDA)
                return new StackPDA($"{kind.ToString()}({Name}+{pda2.Name})", this.StatesCount + pda2.StatesCount + offsetA1, inputAlphabet, workAlphabet, pdat, startState, pda2.StartSymbol);
            else
                throw new System.NotImplementedException();
        }
Exemple #2
0
        IAcceptWord JoinConcatUnion(IAcceptWord automat, JoinConcatUnionKind unionConcatJoinKind)
        {
            if (!(automat is FABase fa2))
            {
                throw new System.NotSupportedException();
            }

            uint offsetA1 = 0;                // first state of A2
            uint offsetA2 = this.StatesCount; // first state of A2

            if (unionConcatJoinKind == JoinConcatUnionKind.Union)
            {
                offsetA1 = 1;
                offsetA2++;
            }

            char[] inputAlphabet = this.Alphabet.Union(fa2.Alphabet).ToArray();

            var neaeT = new NFAeTransform();

            uint startState;

            // Union: add new start state, with e to both starts
            if (unionConcatJoinKind == JoinConcatUnionKind.Union)
            {
                startState = 0;
                neaeT.Add(0, null, this.StartState + offsetA1);
                neaeT.AddM(0, null, fa2.StartState + offsetA2);
            }
            else
            {
                startState = this.StartState;
            }

            // add each A1 transform + offset of A1
            foreach (var item in this.Transforms)
            {
                foreach (var val in item.Value)
                {
                    neaeT.AddM(item.Key.q + offsetA1, item.Key.c, val + offsetA1);
                }
            }

            // add each A1 transform, + offset of A2
            foreach (var item in fa2.Transforms)
            {
                foreach (var val in item.Value)
                {
                    neaeT.AddM(item.Key.q + offsetA2, item.Key.c, val + offsetA2);
                }
            }


            uint[] accStates;
            if (unionConcatJoinKind == JoinConcatUnionKind.Concat)
            {
                // Concat: has only accepted states from A2
                accStates = new uint[fa2.AcceptedStates.Length];
            }
            else
            {
                // Join, Union has A1, A2 accpted states
                accStates = new uint[this.AcceptedStates.Length + fa2.AcceptedStates.Length];
            }

            int i = 0; // store where D1 acc ends

            // iterate A1 acc
            for (; i < this.AcceptedStates.Length; i++)
            {
                if (unionConcatJoinKind == JoinConcatUnionKind.Concat)
                {
                    // Concat: lead accepted states from A1 to A2 start
                    neaeT.AddM(this.AcceptedStates[i] + offsetA1, null, fa2.StartState + offsetA2);
                }
                else
                {
                    // Join, Union: states from A1 are normal accepted
                    accStates[i] = this.AcceptedStates[i] + offsetA1;
                }
            }

            if (unionConcatJoinKind == JoinConcatUnionKind.Concat)
            {
                i = 0;
            }

            // iterate A2 acs and + offsetA2
            for (int j = 0; j < fa2.AcceptedStates.Length; j++)
            {
                accStates[i + j] = (fa2.AcceptedStates[j] + offsetA2);
            }


            return(new NFAe($"NEAe{unionConcatJoinKind.ToString()}({Name}+{fa2.Name})", this.StatesCount + fa2.StatesCount + offsetA1, inputAlphabet, neaeT, startState, accStates));
        }