/* * Copyright (C) 2016 Mostafa M.A. (mostafa.amin93@gmail.com) * Copyright (C) 2014-2016 University of Freiburg * * This file is part of the ULTIMATE Automata Library. * * The ULTIMATE Automata Library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The ULTIMATE Automata Library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the ULTIMATE Automata Library. If not, see . * * Additional permission under GNU GPL version 3 section 7: * If you modify the ULTIMATE Automata Library, or any covered work, by linking * or combining it with Eclipse RCP (or a modified version of Eclipse RCP), * containing parts covered by the terms of the Eclipse Public License, the * licensors of the ULTIMATE Automata Library grant you additional permission * to convey the resulting work. */ package de.uni_freiburg.informatik.ultimate.automata.tree.operations; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.Set; import de.uni_freiburg.informatik.ultimate.automata.AutomataLibraryException; import de.uni_freiburg.informatik.ultimate.automata.AutomataLibraryServices; import de.uni_freiburg.informatik.ultimate.automata.IOperation; import de.uni_freiburg.informatik.ultimate.automata.statefactory.IStateFactory; import de.uni_freiburg.informatik.ultimate.automata.tree.IRankedLetter; import de.uni_freiburg.informatik.ultimate.automata.tree.ITreeAutomatonBU; import de.uni_freiburg.informatik.ultimate.automata.tree.Tree; import de.uni_freiburg.informatik.ultimate.automata.tree.TreeAutomatonRule; import de.uni_freiburg.informatik.ultimate.automata.tree.TreeRun; /** * Operation of a treeAutomaton accepts a given Run. * * @author mostafa (mostafa.amin93@gmail.com) * * @param * letter of the tree automaton. * @param * state of the tree automaton. */ public class Accepts implements IOperation> { private final ITreeAutomatonBU mTreeAutomaton; private final Tree mExample; private final Boolean mResult; /*** * Operator to check if accepting a given tree run by a given tree * automaton. * * @param services * @param automaton * @param run */ public Accepts(final AutomataLibraryServices services, final ITreeAutomatonBU automaton, final TreeRun run) { this(services, automaton, run.getTree()); } /*** * Operator to check if accepting a given tree by a given tree automaton. * * @param services * @param automaton * @param run */ public Accepts(final AutomataLibraryServices services, final ITreeAutomatonBU automaton, final Tree run) { mExample = run; mTreeAutomaton = automaton; mResult = computeResult(); } @Override public String startMessage() { return "Start " + getOperationName(); } @Override public String exitMessage() { return "Exit " + getOperationName(); } /** * * @param t a subtree * @return Set of states that the automaton may be in after reading subtree t */ private Set checkTree(final Tree t) { final ArrayList> statesReachableFromChildren = new ArrayList<>(); for (final Tree ch : t.getChildren()) { Set childResult = checkTree(ch); if (childResult.isEmpty()) { // one of the child subtrees does not have a derivation -- we can reject right here return Collections.emptySet(); } statesReachableFromChildren.add(childResult); } final Iterable> rulesForCurrentLetter = mTreeAutomaton.getSuccessors(t.getSymbol()); if (rulesForCurrentLetter == null) { // there is no rule we can go on with from the current letter return Collections.emptySet(); } final Set res = new HashSet<>(); for (final TreeAutomatonRule rule : rulesForCurrentLetter) { assert rule.getArity() == statesReachableFromChildren.size(); boolean validDerivation = true; for (int i = 0; i < rule.getArity(); ++i) { final STATE sr = rule.getSource().get(i); if (!statesReachableFromChildren.get(i).contains(sr)) { validDerivation = false; break; } } if (validDerivation) { res.add(rule.getDest()); } } return res; } private Boolean computeResult() { final Set derivations = checkTree(mExample); for (final STATE st : derivations) { if (mTreeAutomaton.isFinalState(st)) { return true; } } return false; } @Override public Boolean getResult() { return mResult; } @Override public boolean checkResult(final IStateFactory stateFactory) throws AutomataLibraryException { // TODO implement a meaningful check return true; } }