001/**
002 * Copyright (C) 2007 - 2016, Jens Lehmann
003 *
004 * This file is part of DL-Learner.
005 *
006 * DL-Learner is free software; you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation; either version 3 of the License, or
009 * (at your option) any later version.
010 *
011 * DL-Learner is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014 * GNU General Public License for more details.
015 *
016 * You should have received a copy of the GNU General Public License
017 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
018 */
019package org.dllearner.core.ref;
020
021import java.util.SortedSet;
022
023import org.dllearner.core.ComponentInitException;
024import org.dllearner.core.LearningAlgorithm;
025
026/**
027 * @author Lorenz Buehmann
028 *
029 */
030public abstract class RefinementOperatorBasedLearningAlgorithmBase<T> implements LearningAlgorithm{
031        
032        protected SearchTree<T, SearchTreeNode<T>> searchTree;
033        
034        protected SearchTreeNode<T> startNode;
035        
036        protected RefinementOperator<T> refinementOperator;
037        
038        protected SearchTreeHeuristic<T> heuristic;
039        
040        /* (non-Javadoc)
041         * @see org.dllearner.core.Component#init()
042         */
043        @Override
044        public void init() throws ComponentInitException {
045                // compute the start node
046                startNode = computeStartNode();
047        }
048        
049        /* (non-Javadoc)
050         * @see org.dllearner.core.LearningAlgorithm#start()
051         */
052        @Override
053        public void start() {
054                // apply some pre-processing
055                preProcess();
056                
057                // start with empty search tree
058                searchTree = new SearchTree<>(heuristic);
059        
060                // add start node to search tree
061                searchTree.addNode(startNode);
062                
063                while(!terminationCriteriaSatisfied()) {
064                        // pick best node from search tree
065                        SearchTreeNode<T> currentNode = getNextNodeToExpand();
066                        
067                        // refine node
068                        SortedSet<T> refinements = refineNode(currentNode);
069                        
070                        // add each refinement to search tree
071                        for (T refinement : refinements) {
072                                addToSearchTree(refinement, currentNode);
073                        }
074                }
075                
076                // apply some post-processing
077                postProcess();
078        }
079        
080        protected SortedSet<T> refineNode(SearchTreeNode<T> node) {
081                return refinementOperator.refineNode(node.getData());
082        }
083        
084        /**
085         * Checks whether the refinement is allowed to be added to the search tree 
086         * first by calling {@link #isValid(T refinement)}}, and if yes creates a
087         * new node which is added to the search tree.
088         * @param refinement the refinement
089         * @param parentNode the parent node
090         * @return whether the refinement is allowed to be added to the search tree
091         */
092        protected boolean addToSearchTree(T refinement, SearchTreeNode<T> parentNode) {
093                // check if the refinement is allowed
094                boolean isValid = isValid(refinement);
095                
096                // only if it's allowed
097                if(isValid) {
098                        // create a new node
099                        SearchTreeNode<T> node = createNode(refinement, parentNode);
100                        
101                        // add to search tree
102                        return searchTree.addNode(node);
103                }
104                
105                // otherwise return FALSE
106                return false;
107        }
108        
109        protected SearchTreeNode<T> createNode(T refinement, SearchTreeNode<T> parentNode) {
110                return new SearchTreeNodeSimple<>(refinement, parentNode);
111        }
112        
113        protected void preProcess() {}
114
115        protected void postProcess() {}
116
117        protected abstract SearchTreeNode<T> computeStartNode();
118        
119        protected abstract SearchTreeNode<T> getNextNodeToExpand();
120        
121        
122        /**
123         * Checks whether the object is valid for further refinement
124         * @param refinement the refinement
125         * @return whether the object is valid for further refinement
126         */
127        protected abstract boolean isValid(T refinement);
128        
129        /**
130         * Checks whether the algorithm has to be terminated.
131         * @return whether the algorithm has to be terminated
132         */
133        protected abstract boolean terminationCriteriaSatisfied();
134        
135        
136        
137
138}