//package uk.ac.man.cs.lethe.dl.abduction.experiments;
//
//import org.semanticweb.HermiT.Reasoner;
//import org.semanticweb.owlapi.apibinding.OWLManager;
//import org.semanticweb.owlapi.model.*;
//import org.semanticweb.owlapi.model.parameters.Imports;
//import org.semanticweb.owlapi.reasoner.OWLReasoner;
//
//import java.util.*;
//
//public class ObservationGenerator {
//    //private int numToGenerate;
//    //private int maxAttempts;
//    private Random rand;
//    int numAttempts;
//    int numResets;
//
//    private boolean checkObservations = true;
//
//    public ObservationGenerator() {
//        this.rand = new Random();
//        this.numAttempts = 0;
//        this.numResets = 0;
//    }
//
//    public ObservationGenerator(boolean checkObservations) {
//	this();
//        this.checkObservations=checkObservations;
//    }
//
//    public Set<OWLAxiom> extractObservation(OWLOntology backgroundOntology, int observationSize) throws OWLOntologyCreationException {
//        Set<OWLAxiom> observations = new HashSet<OWLAxiom>();
//
//        //select axioms
//        observations.addAll(selectRandomObservations(backgroundOntology, observationSize));
//
//        //generate abox
//        //observations.addAll(generateABoxObservations(backgroundOntology, observationSize));
//
//        System.out.println("Observation:");
//        for(OWLAxiom obs:  observations) {
//            System.out.println(uk.ac.man.cs.lethe.internal.tools.formatting.SimpleOWLFormatter.format(obs));
//        }
//
//        return checkAndReturnObservations(observations, backgroundOntology);
//    }
//
//    public Set<OWLAxiom> checkAndReturnObservations(Set<OWLAxiom> observation, OWLOntology backgroundOntology)  {
//
//        if (checkObservations) {
//            backgroundOntology.removeAxioms(observation);
//            OWLReasoner res = new Reasoner.ReasonerFactory().createReasoner(backgroundOntology);
//
//
//            //System.out.println("OBSERVATION: " + observations);
//            if (res.isConsistent() == false) {
//                System.out.println("Observation generation failed: inconsistent. Skipping.");
//                numAttempts++;
//                //return selectRandomObservation(backgroundOntology, numTBox, numABox);
//                return null;
//            } else if (!res.isEntailed(observation)) {
//                return observation;
//            } else {
//                System.out.println("Observations do not satisfy abduction problem. Skipping.");
//
//                numAttempts++;
//                //return selectRandomObservation(backgroundOntology, numTBox, numABox);
//                return null;
//            }
//        } else {
//            return observation;
//        }
//    }
//
//    /*
//    public Set<OWLAxiom> extractObservation(OWLOntology backgroundOntology, int numTBox, int numABox) throws OWLOntologyCreationException {
//        Set<OWLAxiom> observations = new HashSet<OWLAxiom>();
//
//        //select tbox
//        observations.addAll(selectRandomObservations(backgroundOntology, numTBox, 0));
//
//        //select abox
//        observations.addAll(selectRandomObservations(backgroundOntology, 0, numABox));
//
//        //generate abox
//        //observations.addAll(generateABoxObservations(backgroundOntology, numABox));
//        return checkAndReturnObservations(observations,backgroundOntology);
//	}*/
//
//    public Set<OWLAxiom> selectRandomObservations(OWLOntology backgroundOntology, int observationsNum) {
//        List<OWLAxiom> backgroundAxioms = new ArrayList<OWLAxiom>(backgroundOntology.getLogicalAxioms(Imports.fromBoolean(false)));
//
//        Set<OWLAxiom> observations = new HashSet<OWLAxiom>();
//
//
//        int numAdded = 0;
//        while(numAdded < observationsNum) {
//            OWLAxiom selectedAx = backgroundAxioms.get(rand.nextInt(backgroundAxioms.size()));
//            //System.out.println("axtype: " + selectedAx.getAxiomType().toString());
//            if(!observations.contains(selectedAx)){
//                numAdded++;
//                observations.add(selectedAx);
//            }
//        }
//
//        return observations;
//    }
//
//
//    /*    public Set<OWLAxiom> selectRandomObservations(OWLOntology backgroundOntology, int numTBox, int numABox) {
//        List<OWLAxiom> backgroundTBoxAxioms = new ArrayList<OWLAxiom>(backgroundOntology.getTBoxAxioms(Imports.fromBoolean(false)));
//        List<OWLAxiom> backgroundABoxAxioms = new ArrayList<OWLAxiom>(backgroundOntology.getABoxAxioms(Imports.fromBoolean(false)));
//
//        OWLOntologyManager man = OWLManager.createOWLOntologyManager();
//        Set<OWLAxiom> observations = new HashSet<OWLAxiom>();
//
//        //if obs too large, scale to size of small ontology TODO: decide if there is better/preferred way
//        if(numTBox >= backgroundTBoxAxioms.size()) {
//            numTBox = rand.nextInt((int) Math.ceil(0.5 * backgroundTBoxAxioms.size()));
//        }
//        if(numABox > backgroundABoxAxioms.size()) {
//            numABox = rand.nextInt((int) Math.ceil(0.5 * backgroundABoxAxioms.size()));
//        }
//        if(numABox == 0 && numTBox == 0) {
//            if(backgroundABoxAxioms.size() != 0) {
//                numABox = 1; //minimally sized observation, not empty
//            }
//            else {
//                numTBox = 1;
//            }
//        }
//
//        int numAdded = 0;
//        while(numAdded < numTBox) {
//            OWLAxiom selectedAx = backgroundTBoxAxioms.get(rand.nextInt(backgroundTBoxAxioms.size()));
//            //System.out.println("axtype: " + selectedAx.getAxiomType().toString());
//            if(!observations.contains(selectedAx)){
//                numAdded++;
//                observations.add(selectedAx);
//            }
//        }
//
//        numAdded = 0;
//        while(numAdded < numABox) {
//            OWLAxiom selectedAx = backgroundABoxAxioms.get(rand.nextInt(backgroundABoxAxioms.size()));
//            if(!observations.contains(selectedAx)) {
//                numAdded++;
//                observations.add(selectedAx);
//            }
//        }
//
//        return observations;
//    }
//*/
//    public Set<OWLAxiom> generateABoxObservations(OWLOntology backgroundOntology, int numAxioms) {
//        OWLOntologyManager man = OWLManager.createOWLOntologyManager();
//        OWLDataFactory df = man.getOWLDataFactory();
//
//        //generate individual names
//        List<OWLNamedIndividual> freshIndividuals = new ArrayList<OWLNamedIndividual>();
//        int numFreshIndividuals = rand.nextInt(3) + 2; //gen between 2-5 individuals
//        for(int i=0;i<numFreshIndividuals;i++) {
//            freshIndividuals.add(df.getOWLNamedIndividual(IRI.create(backgroundOntology.getOntologyID().getOntologyIRI() + "#freshIndividual" + i)));
//        }
//
//        //generate assertions
//        List<OWLAxiom> backgroundAxioms = new ArrayList<OWLAxiom>(backgroundOntology.getLogicalAxioms());
//        Set<OWLAxiom> generatedAssertions = new HashSet<OWLAxiom>();
//        for(int i=0; i<numAxioms; i++) {
//            OWLAxiom ax = backgroundAxioms.get(rand.nextInt(backgroundAxioms.size()));
//            List<OWLEntity> symbols = new ArrayList<OWLEntity>(ax.getSignature());//.removeAll(ax.getIndividualsInSignature());
//            symbols.removeAll(ax.getIndividualsInSignature());
//
//            OWLEntity chosenSymbol = symbols.get(rand.nextInt(symbols.size()));
//            if(chosenSymbol instanceof OWLClass) {
//                OWLClassAssertionAxiom as = df.getOWLClassAssertionAxiom(((OWLClass) chosenSymbol), freshIndividuals.get(rand.nextInt(freshIndividuals.size())));
//                generatedAssertions.add(as);
//                //System.out.println("generated assertion: " + as);
//            }
//            else if(chosenSymbol instanceof OWLObjectProperty) {
//                OWLNamedIndividual indiv1 = freshIndividuals.get(rand.nextInt(freshIndividuals.size()));
//                freshIndividuals.remove(indiv1);
//                OWLNamedIndividual indiv2 = freshIndividuals.get(rand.nextInt(freshIndividuals.size()));
//                freshIndividuals.add(indiv1);
//
//                OWLObjectPropertyAssertionAxiom as = df.getOWLObjectPropertyAssertionAxiom(((OWLObjectProperty) chosenSymbol), indiv1, indiv2);
//                generatedAssertions.add(as);
//                //System.out.println("generated assertion: " + as);
//            }
//            else {
//                System.out.println("Neither class nor property: error in obs generation: " + chosenSymbol);
//            }
//        }
//
//        return checkAndReturnObservations(generatedAssertions, backgroundOntology);
//    }
//
//    //=======================
//
//    public void setSeed(int rngSeed){
//        this.rand = new Random(rngSeed);
//    }
//
//    public void restartGenerator(){
//        this.numAttempts = 0;
//        this.numResets = 0;
//    }
//
//}
