julianthome/autorex

View on GitHub
src/main/java/org/snt/autorex/Converter.java

Summary

Maintainability
A
2 hrs
Test Coverage
/**
 * autorex - fsm state eliminator
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2016 Julian Thome <julian.thome.de@gmail.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is furnished to do
 * so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 **/

package org.snt.autorex;

import dk.brics.automaton.Automaton;
import dk.brics.automaton.State;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.snt.autorex.autograph.Gnfa;
import org.snt.autorex.autograph.Transition;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * Utility class for converting an dk.brics automaton into our gnfa
 * representation
 */
public enum Converter {

    INSTANCE;

    final static Logger LOGGER = LoggerFactory.getLogger(Converter.class);

    public Gnfa getGnfaFromAutomaton(Automaton auto) {
        return getGnfaFromAutomaton(auto, new DefaultLabelTranslator());
    }

    /**
     * convert dk.brics automaton into gnfa
     * @param auto dk.brics automaton
     * @param ltrans label translator
     *
     * @return generalized non-deterministic finite automaton
     */
    public Gnfa getGnfaFromAutomaton(Automaton auto, LabelTranslator ltrans) {
        Gnfa ag = new Gnfa();
        AutomatonTrans at = new AutomatonTrans(auto, ltrans);

        Map<State,org.snt.autorex.autograph.State> smap = new HashMap<>();
        Set<org.snt.autorex.autograph.State> accepting = new HashSet<>();
        Set<org.snt.autorex.autograph.State> start = new HashSet<>();

        org.snt.autorex.autograph.State end =  new org.snt.autorex.autograph
                .State(org.snt.autorex
                .autograph.State.Kind.ACCEPT);

        org.snt.autorex.autograph.State init =  new org.snt.autorex.autograph
                .State(org.snt.autorex
                .autograph.State.Kind.START);

        ag.addVertex(end);
        ag.addVertex(init);


        for(FullTransition ft : at.transitions){
            State src = ft.getSourceState();
            State dst = ft.getTargetState();

            org.snt.autorex.autograph.State arxsrc = getStateFrom(start,
                    accepting, smap, at, src);
            org.snt.autorex.autograph.State arxdst = getStateFrom(start,
                    accepting, smap, at, dst);

            Transition t = null;
            if(ag.containsEdge(arxsrc, arxdst)) {
                t = ag.getEdge(arxsrc, arxdst);
                t.getLabel().append("|");
                t.getLabel().append(ft
                        .getTransitionLabel());
            } else {
                t = new Transition(arxsrc, arxdst, Transition.Kind
                        .MATCH,ft
                        .getTransitionLabel());
            }

            ag.addVertex(arxdst);
            ag.addVertex(arxsrc);
            ag.addEdge(t);
        }

        accepting.forEach(
            a -> {
                Transition t = new Transition(a,end,Transition.Kind
                        .EPSILON);
                ag.addEdge(t);
            }
        );

        start.forEach(
                a -> {
                    Transition t = new Transition(init,a, Transition.Kind
                            .EPSILON);
                    ag.addEdge(t);
                }
        );

        return ag;
    }


    private org.snt.autorex.autograph.State getStateFrom
            (Set<org.snt.autorex.autograph.State> start,
             Set<org.snt.autorex.autograph.State> accepting,
             Map<State,org.snt.autorex.autograph.State> smap,
             AutomatonTrans a, State s) {

        if(smap.containsKey(s))
            return smap.get(s);

        org.snt.autorex.autograph.State ret = new org.snt.autorex.autograph
                .State(org.snt.autorex
                .autograph.State.Kind.NORMAL);

        if(s.isAccept()) {
            accepting.add(ret);
        }

        if(s.equals(a.init)) {
            start.add(ret);
        }

        smap.put(s,ret);

        return ret;
    }
}