All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.learnlib.algorithm.aaar.abstraction.AbstractAbstractionTree Maven / Gradle / Ivy

Go to download

This artifact provides the implementation of the AAAR learning algorithm as described in the paper "Automata Learning with Automated Alphabet Abstraction Refinement" (https://dx.doi.org/10.1007/978-3-642-18275-4_19) by Falk Howar, Bernhard Steffen, and Maik Merten.

The newest version!
/* Copyright (C) 2013-2023 TU Dortmund
 * This file is part of LearnLib, http://www.learnlib.de/.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package de.learnlib.algorithm.aaar.abstraction;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Queue;

import de.learnlib.algorithm.aaar.Abstraction;
import de.learnlib.algorithm.aaar.abstraction.Node.InnerNode;
import de.learnlib.algorithm.aaar.abstraction.Node.Leaf;
import de.learnlib.oracle.MembershipOracle;
import net.automatalib.graph.Graph;
import net.automatalib.graph.concept.GraphViewable;
import net.automatalib.visualization.DefaultVisualizationHelper;
import net.automatalib.visualization.VisualizationHelper;
import net.automatalib.word.Word;

public abstract class AbstractAbstractionTree
        implements Abstraction, GraphViewable, Graph {

    private Node root;

    private final MembershipOracle oracle;

    private final Map gamma;

    public AbstractAbstractionTree(AI rootA, CI rootC, MembershipOracle o) {
        this.root = new Leaf<>(rootA, rootC);
        this.oracle = o;

        this.gamma = new HashMap<>();
        this.gamma.put(rootA, rootC);
    }

    public AI splitLeaf(CI repOld, CI repNew, Word prefix, Word suffix, D outOld) {

        final Leaf l = new Leaf<>(createAbstractionForRepresentative(repNew), repNew);
        gamma.put(l.abs, repNew);

        Node cur = root;
        Node parent = null;

        while (cur instanceof InnerNode) {
            @SuppressWarnings("unchecked")
            final InnerNode n = (InnerNode) cur;
            final Word test = n.prefix.append(repOld).concat(n.suffix);
            final D out = oracle.answerQuery(test);

            parent = cur;
            if (Objects.equals(n.out, out)) {
                cur = n.equalsNext;
            } else {
                cur = n.otherNext;
            }

        }

        final InnerNode newNode = new InnerNode<>(prefix, suffix, outOld, cur, l);

        if (parent == null) {
            root = newNode;
        } else {
            final InnerNode parentAsInner = (InnerNode) parent;
            if (parentAsInner.equalsNext == cur) {
                parentAsInner.equalsNext = newNode;
            } else {
                parentAsInner.otherNext = newNode;
            }
        }

        return l.abs;
    }

    @Override
    public AI getAbstractSymbol(CI c) {
        Node cur = root;

        while (cur instanceof InnerNode) {
            @SuppressWarnings("unchecked")
            final InnerNode n = (InnerNode) cur;
            final Word test = n.prefix.append(c).concat(n.suffix);
            final D out = oracle.answerQuery(test);

            if (Objects.equals(n.out, out)) {
                cur = n.equalsNext;
            } else {
                cur = n.otherNext;
            }
        }

        @SuppressWarnings("unchecked")
        final Leaf leaf = (Leaf) cur;
        return leaf.abs;
    }

    @Override
    public CI getRepresentative(AI a) {
        final CI ci = gamma.get(a);
        assert ci != null;
        return ci;
    }

    public Collection getRepresentativeSymbols() {
        return Collections.unmodifiableCollection(this.gamma.values());
    }

    @Override
    public Graph graphView() {
        return this;
    }

    @Override
    public Collection getOutgoingEdges(Node node) {
        if (node instanceof InnerNode) {
            final InnerNode n = (InnerNode) node;
            return Arrays.asList(n.equalsNext, n.otherNext);
        }

        return Collections.emptySet();
    }

    @Override
    public Node getTarget(Node edge) {
        return edge;
    }

    @Override
    public Collection getNodes() {

        final List result = new ArrayList<>(this.gamma.size());

        final Queue nodes = new ArrayDeque<>();
        nodes.add(root);

        while (!nodes.isEmpty()) {
            final Node n = nodes.poll();
            if (n instanceof InnerNode) {
                final InnerNode in = (InnerNode) n;
                result.add(in);
                nodes.add(in.equalsNext);
                nodes.add(in.otherNext);
            } else {
                assert n != null;
                result.add(n);
            }
        }

        return result;
    }

    @Override
    public VisualizationHelper getVisualizationHelper() {
        return new DefaultVisualizationHelper() {

            @Override
            public boolean getNodeProperties(Node node, Map properties) {
                super.getNodeProperties(node, properties);

                if (node instanceof InnerNode) {
                    final InnerNode n = (InnerNode) node;
                    properties.put(NodeAttrs.LABEL, n.prefix + ", " + n.suffix);
                } else if (node instanceof Leaf) {
                    final Leaf l = (Leaf) node;
                    properties.put(NodeAttrs.LABEL, String.format("Abs.: '%s'%nRep.: '%s'", l.abs, l.rep));
                }

                return true;
            }

            @Override
            public boolean getEdgeProperties(Node src, Node edge, Node tgt, Map properties) {
                super.getEdgeProperties(src, edge, tgt, properties);

                if (src instanceof InnerNode) {
                    final InnerNode n = (InnerNode) src;
                    if (n.equalsNext == tgt) {
                        properties.put(EdgeAttrs.LABEL, "== " + n.out);
                    } else {
                        properties.put(EdgeAttrs.LABEL, "!= " + n.out);
                        properties.put(EdgeAttrs.STYLE, EdgeStyles.DASHED);
                    }
                }

                return true;
            }
        };
    }

    protected abstract AI createAbstractionForRepresentative(CI ci);
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy