Search in sources :

Example 1 with CharObjectHashMap

use of org.eclipse.collections.impl.map.mutable.primitive.CharObjectHashMap in project narchy by automenta.

the class DFA method minimize.

private int[][] minimize(Map<Set<NFAState>, CharObjectHashMap<Set<NFAState>>> oriDFATransitionMap, Set<NFAState> initClosure, NFAState finalNFAState) {
    Map<Integer, int[]> renamedDFATransitionTable = new HashMap<>();
    Map<Integer, Boolean> finalFlags = new HashMap<>();
    Map<Set<NFAState>, Integer> stateRenamingMap = new HashMap<>();
    int initStateAfterRenaming = -1;
    int renamingStateID = 1;
    // rename all states
    for (Set<NFAState> nfaState : oriDFATransitionMap.keySet()) {
        if (initStateAfterRenaming == -1 && nfaState.equals(initClosure)) {
            // record init state id
            initStateAfterRenaming = renamingStateID;
        }
        stateRenamingMap.put(nfaState, renamingStateID++);
    }
    // the rejected state 0
    renamedDFATransitionTable.put(0, newRejectState());
    finalFlags.put(0, false);
    // construct renamed dfa transition table
    for (Map.Entry<Set<NFAState>, CharObjectHashMap<Set<NFAState>>> entry : oriDFATransitionMap.entrySet()) {
        Set<NFAState> ek = entry.getKey();
        renamingStateID = stateRenamingMap.get(ek);
        int[] state = newRejectState();
        CharObjectHashMap<Set<NFAState>> ev = entry.getValue();
        ev.forEachKeyValue((k, v) -> state[k] = stateRenamingMap.get(v));
        renamedDFATransitionTable.put(renamingStateID, state);
        finalFlags.put(renamingStateID, ek.contains(finalNFAState));
    }
    // split states to final states and non-final states
    IntIntHashMap groupFlags = new IntIntHashMap();
    for (int i = 0; i < finalFlags.size(); i++) {
        boolean b = finalFlags.get(i);
        groupFlags.put(i, b ? 0 : 1);
    }
    int groupTotal = 2;
    int preGroupTotal;
    do {
        // splitting, group id is the final state id
        preGroupTotal = groupTotal;
        for (int sensitiveGroup = 0; sensitiveGroup < preGroupTotal; sensitiveGroup++) {
            // <target group table, state id set>
            Map<Map<Integer, Integer>, Set<Integer>> invertMap = new HashMap<>();
            for (int sid = 0; sid < groupFlags.size(); sid++) {
                // use state id to iterate
                int group = groupFlags.get(sid);
                if (sensitiveGroup == group) {
                    Map<Integer, Integer> targetGroupTable = new HashMap<>(CommonSets.ENCODING_LENGTH);
                    for (char ch = 0; ch < CommonSets.ENCODING_LENGTH; ch++) {
                        int targetState = renamedDFATransitionTable.get(sid)[ch];
                        int targetGroup = groupFlags.get(targetState);
                        targetGroupTable.put((int) ch, targetGroup);
                    }
                    Set<Integer> stateIDSet = invertMap.computeIfAbsent(targetGroupTable, k -> new HashSet<>());
                    stateIDSet.add(sid);
                }
            }
            boolean first = true;
            for (Set<Integer> stateIDSet : invertMap.values()) {
                if (first) {
                    first = false;
                } else {
                    for (int sid : stateIDSet) {
                        groupFlags.put(sid, groupTotal);
                    }
                    groupTotal++;
                }
            }
        }
    } while (preGroupTotal != groupTotal);
    // determine initial group state
    is = groupFlags.get(initStateAfterRenaming);
    // determine rejected group state
    rs = groupFlags.get(0);
    // determine final group states
    Set<Integer> finalGroupFlags = new HashSet<>();
    for (int i = 0, groupFlagsSize = groupFlags.size(); i < groupFlagsSize; i++) {
        Integer groupFlag = groupFlags.get(i);
        if (finalFlags.get(i)) {
            finalGroupFlags.add(groupFlag);
        }
    }
    boolean[] fs = this.fs = new boolean[groupTotal];
    for (int i = 0; i < groupTotal; i++) {
        fs[i] = finalGroupFlags.contains(i);
    }
    // construct the final transition table
    int[][] tt = new int[groupTotal][];
    for (int groupID = 0; groupID < groupTotal; groupID++) {
        for (int sid = 0; sid < groupFlags.size(); sid++) {
            if (groupID == groupFlags.get(sid)) {
                int[] oriState = renamedDFATransitionTable.get(sid);
                int[] state = new int[CommonSets.ENCODING_LENGTH];
                for (char ch = 0; ch < CommonSets.ENCODING_LENGTH; ch++) {
                    int next = oriState[ch];
                    state[ch] = groupFlags.get(next);
                }
                tt[groupID] = state;
                break;
            }
        }
    }
    return tt;
}
Also used : CharObjectHashMap(org.eclipse.collections.impl.map.mutable.primitive.CharObjectHashMap) IntIntHashMap(org.eclipse.collections.impl.map.mutable.primitive.IntIntHashMap) IntIntHashMap(org.eclipse.collections.impl.map.mutable.primitive.IntIntHashMap) CharObjectHashMap(org.eclipse.collections.impl.map.mutable.primitive.CharObjectHashMap) CharObjectHashMap(org.eclipse.collections.impl.map.mutable.primitive.CharObjectHashMap) IntIntHashMap(org.eclipse.collections.impl.map.mutable.primitive.IntIntHashMap)

Aggregations

CharObjectHashMap (org.eclipse.collections.impl.map.mutable.primitive.CharObjectHashMap)1 IntIntHashMap (org.eclipse.collections.impl.map.mutable.primitive.IntIntHashMap)1