/* * Copyright (C) 2020 Matthias Heizmann (heizmann@informatik.uni-freiburg.de) * Copyright (C) 2020 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.counting; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Map; 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.core.model.services.ILogger; /** * Union method for Counting Automata * * @author Marcel Ebbinghaus * @author who is the author? */ public class Union> implements IOperation { private final AutomataLibraryServices mServices; private final ILogger mLogger; private final CountingAutomaton mFstOperand; private final CountingAutomaton mSndOperand; private final STATE mNewInitialState; private final CountingAutomaton mResult; private final ICaUnionStateFactory mStateFactory; public Union( final AutomataLibraryServices services, final ICaUnionStateFactory stateFactory, final CountingAutomaton fstOperand, final CountingAutomaton sndOperand) throws AutomataLibraryException { mServices = services; mLogger = mServices.getLoggingService().getLogger(this.getClass()); mFstOperand = fstOperand; mSndOperand = sndOperand; mStateFactory = stateFactory; mNewInitialState = mStateFactory.constructInitialState(); if (mLogger.isInfoEnabled()) { mLogger.info(startMessage()); } mResult = computeResult(); if (mLogger.isInfoEnabled()) { mLogger.info(exitMessage()); } } private CountingAutomaton computeResult() { final Set unionAlphabet = mFstOperand.getAlphabet(); final ArrayList unionCounter = new ArrayList(); for (final Counter counter : mFstOperand.getCounter()) { unionCounter.add(counter.copyCounter()); } for (final Counter counter : mSndOperand.getCounter()) { unionCounter.add(counter.copyCounter()); } final Set unionStates = new HashSet(); unionStates.addAll(mFstOperand.getStates()); unionStates.addAll(mSndOperand.getStates()); unionStates.add(mNewInitialState); final Map unionInitialConditions = new HashMap(); final Map unionFinalConditions = new HashMap(); final Map>> unionTransitions = new HashMap>>(); //initialConditions final Guard newInitialGuard = new Guard(); newInitialGuard.changeTermType(TermType.TRUE); final ArrayList newGuardList = new ArrayList(); newGuardList.add(newInitialGuard); final ArrayList> newInitialConditionList = new ArrayList>(); newInitialConditionList.add(newGuardList); unionInitialConditions.put(mNewInitialState, new InitialCondition(newInitialConditionList)); addNewUnionInitialConditions(mFstOperand, unionInitialConditions); addNewUnionInitialConditions(mSndOperand, unionInitialConditions); //finalConditions final ArrayList> newFinalConditionList = new ArrayList>(); addNewUnionFinalConditions(mFstOperand, newFinalConditionList, unionFinalConditions); addNewUnionFinalConditions(mSndOperand, newFinalConditionList, unionFinalConditions); //construct finalCondition == false, if there were no states in mFstOperand and mSndOperand which are initial and final at once if (newFinalConditionList.size() == 0) { final Guard newGuardFalse = new Guard(); newGuardFalse.changeTermType(TermType.FALSE); final ArrayList guardList = new ArrayList(); guardList.add(newGuardFalse); newFinalConditionList.add(guardList); } unionFinalConditions.put(mNewInitialState, new FinalCondition(newFinalConditionList)); //transitions final ArrayList> newTransitions = new ArrayList>(); addNewUnionTransitions(mFstOperand, newTransitions, unionTransitions); addNewUnionTransitions(mSndOperand, newTransitions, unionTransitions); unionTransitions.put(mNewInitialState, newTransitions); //result final CountingAutomaton resultAutomaton = new CountingAutomaton( mServices, unionAlphabet, unionStates, unionCounter, unionInitialConditions, unionFinalConditions, unionTransitions); return resultAutomaton; } private void addNewUnionInitialConditions (final CountingAutomaton automaton, final Map unionInitialConditions) { for (final STATE state : automaton.getStates()) { final Guard newInitialGuard = new Guard(); newInitialGuard.changeTermType(TermType.FALSE); final ArrayList newGuardList = new ArrayList(); newGuardList.add(newInitialGuard); final ArrayList> newInitialConditionList = new ArrayList>(); newInitialConditionList.add(newGuardList); unionInitialConditions.put(state, new InitialCondition(newInitialConditionList)); } } private void addNewUnionFinalConditions (final CountingAutomaton automaton, final ArrayList> newFinalConditionList, final Map unionFinalConditions) { for (final STATE state : automaton.getStates()) { unionFinalConditions.put(state, automaton.getFinalConditions().get(state).copyFinalCondition()); if (automaton.getInitialConditions().get(state).getCondition().get(0).get(0).getTermType() != TermType.FALSE && automaton.getFinalConditions().get(state).getCondition().get(0).get(0).getTermType() != TermType.FALSE) { final ConjunctGuards conjunction = new ConjunctGuards( automaton.getFinalConditions().get(state).copyFinalCondition().getCondition(), automaton.getInitialConditions().get(state).copyInitialCondition().getCondition()); newFinalConditionList.addAll(conjunction.getResult()); } } } private void addNewUnionTransitions (final CountingAutomaton automaton, final ArrayList> newTransitions, final Map>> unionTransitions) { for (final STATE state : automaton.getStates()) { final ArrayList> transitionList = new ArrayList>(); for (final Transition transition : automaton.getTransitions().get(state)) { final Transition transitionCopy = transition.copyTransition(); transitionList.add(transitionCopy); } unionTransitions.put(state, transitionList); if (automaton.getInitialConditions().get(state).getCondition().get(0).get(0).getTermType() != TermType.FALSE) { for (final Transition transition : automaton.getTransitions().get(state)) { final Transition transitionCopy = transition.copyTransition(); final ConjunctGuards conjunction = new ConjunctGuards(transitionCopy.getGuards(), automaton.getInitialConditions().get(state).copyInitialCondition().getCondition()); final Transition newTransition = new Transition( transitionCopy.getLetter(), mNewInitialState, transitionCopy.getSucState(), conjunction.getResult(), transitionCopy.getUpdates()); newTransitions.add(newTransition); } } } } @Override public CountingAutomaton getResult() { return mResult; } @Override public boolean checkResult(final CRSF stateFactory) throws AutomataLibraryException { // TODO Auto-generated method stub return true; } }