
// package uk.ac.man.cs.lethe.internal.application.benchmarks

// import java.io.File
// import java.util.Date
// import java.util.concurrent.TimeoutException

// import scala.collection.immutable.TreeSet
// import scala.concurrent._
// import scala.concurrent.duration._
// import scala.io.Source
// import scala.util.Random
// import scala.util.parsing.json.JSON

// import org.semanticweb.owlapi.io.OWLOntologyCreationIOException


// import uk.ac.man.cs.lethe.internal.dl.datatypes.{ Ontology, DLHelpers }
// import dl.OWLOntologyFilters
// import uk.ac.man.cs.lethe.internal.dl.forgetting.{ RoleForgetterS, RoleForgetter }
// import uk.ac.man.cs.lethe.internal.dl.interpolation.OWLApiInterface
// import uk.ac.man.cs.lethe.internal.dl.owlapi.{ OWLParser, OWLExporter, OWLApiConverter }


// object RoleForgettingExperimenterALC { 

//   implicit val exec = new CustomExecutionContext()

//   var benchmarkOntologies: Set[String] = _
  
//   var runsPerOntology: Int = _
  
//   var numsOfWordsToForget: Iterable[Int] = _
  
//   var maxUsageOfWord: Double = _

//   var timeOut: Duration = _

//   val DONT_FORGET = Set() //"by", "for", "of", "Thing", "hasPart", "hasPurpose", "Atom")

//   /**
//    * Load settings from json file.
//    *
//    * The file is expected to have the correct format. No error checking is performed by this function. 
//    */
//   def loadConfiguration(configurationFile: File) = {  
//     val confString = Source.fromFile(configurationFile).getLines().mkString("\n")

//     JSON.parseFull(confString) match { 
//       case Some(map: Map[String, Any]) =>  
// 	benchmarkOntologies = Set()
// 	runsPerOntology = map("runsPerOntology").asInstanceOf[Double].toInt
// 	numsOfWordsToForget = map("numsOfWordsToForget").asInstanceOf[List[Double]].map(_.toInt)
// 	maxUsageOfWord = map("maxUsageOfWord").asInstanceOf[Double]
// 	timeOut = map("timeOut").asInstanceOf[Double].toInt seconds


//         // Check if ontology list is given
//         map.get("benchmarkOntologies") match { 
// 	  case Some(ontologies) => benchmarkOntologies ++= ontologies.asInstanceOf[List[String]]
// 	  case None => ;
// 	}

//         map.get("benchmarkOntologiesDir") match { 
// 	  case Some(dir) => benchmarkOntologies ++= 
// 				    new File(dir.asInstanceOf[String]).listFiles.map(_.getAbsolutePath)
// 	  case None => ;
// 	}

// 	map.get("benchmarkRoot") match { 

// 	  // There is a benchmark root given
// 	  case Some(root) =>
// 	    var benchmark = new Benchmark(new File(root.asInstanceOf[String]))
	  
// 	    // check whether we want to filter the benchmark 
// 	    map.get("expressivities") match { 
// 	      case Some(exps) => 
// 		benchmark = benchmark.filterOntologies("expressivity", exps.asInstanceOf[List[String]])
// 	      case None => ;
// 	    }
// 	    map.get("excludeFamilies") match { 
// 	      case Some(exps) => 
// 		println("Exclude families: "+exps.asInstanceOf[List[String]].mkString(", "))
// 		benchmark = benchmark.filterOutOntologies("expressivity", exps.asInstanceOf[List[String]])
// 	      case None => ;
// 	    }

//             // Add all ontologies of the benchmark
//             benchmarkOntologies ++= benchmark.ontologies
	  
// 	  // There is no benchmark root given
// 	  case None => ;
// 	}

// 	map.get("ignoreOntologies") match { 
// 	  case Some(ontologies) =>
// 	    benchmarkOntologies --= ontologies.asInstanceOf[List[String]]
// 	  case None => ;
// 	}
 
//       case other => println("nothing parsed: "+other.toString)
//     }
//   }
  

//   /**
//    * Run the experiments
//    *
//    * simulate: don't run experiments, just create output
//    * seed: seed for the random number generator
//    * continue: continue canceled experiment, skip all runs below that number
//    */
//   def run(simulate: Boolean, seed: Long, continue: Int) = { 

//     val ran = new Random(seed)

//     println("Seed: "+seed.toString)
//     println("Time-out set to "+timeOut)

//     var counter = 0

//     benchmarkOntologies.toSeq.foreach { ont =>
//       try { 
// 	if(ont!=null) { 
// 	  val owlOntology = try{ 
// 	    OWLApiInterface.getOWLOntology(ont)
// 	  } catch { 
// 	    case _:IllegalArgumentException => OWLApiInterface.getOWLOntology(new File(ont))
// 	  }

// 	  OWLOntologyFilters.restrictToALC(owlOntology)

// 	  val ontology = OWLApiConverter.convert(owlOntology)

// 	  val signature = TreeSet[String]()++(ontology.roleSymbols -- DONT_FORGET)

// 	  numsOfWordsToForget.foreach { numOfWordsToForget => 
// 	    if(numOfWordsToForget<signature.size)
// 	      for(i <- 1 to runsPerOntology) { 

// 		val output = ont+"_"+numOfWordsToForget+"_"+i+".owl"
		  
// 		if(new File(output).exists())
// 		  println(output+" exists. Skipping.")
// 		else{ 
// 		  val wordsToForget = ran.shuffle(signature.toSeq).slice(0, numOfWordsToForget).toSet
// 		  if(counter>=continue){ 
// 		    println("\n\n\n\nExperiment number: "+counter.toString)
// 		    println("Ontology: "+ont)
// 		    println("Axioms: "+ontology.statements.size)
// 		    println("Max axiom size: "+ontology.statements.map(_.size).max)
// 		    println("Words to forget: "+numOfWordsToForget)
// 		    println("Run number: "+i)
		    
// 		    if(!simulate){ 
// 		      val wordsToForget = ran.shuffle(signature.toSeq).slice(0, numOfWordsToForget).toSet
// 		      val ontology = OWLApiConverter.convert(owlOntology)
// 		      if(counter<continue){
// 			println("skipped")
// 		      }else { 		      
// 			println("Size: "+ontology.size)
// 			println("Axioms: "+ontology.tbox.axioms.size)
// 			println()
// 			println("Forgetting the following words: "+wordsToForget)
// 			println()
// 			println("Started at "+(new Date()).toString)
// 			println()
			
// 			val futureResult = future[Ontology]{ 
// 			  RoleForgetterS.forget(ontology, wordsToForget)
// 			}
			
// 			try { 
// 			  var result = Await.result(futureResult, timeOut)
// 			  println("Size of the output: "+result.size)
// 			  println("Number of axioms: "+result.tbox.axioms.size)
// 			  println("Max axiom size (output): "+result.statements.map(_.size).max)
// 			  result = DLHelpers.splitConjunctions(result)
// 			  println("Size of the output (split conjunctions): "+result.size)
// 			  println("Number of axioms (split conjunctions): "+result.tbox.axioms.size)
// 			  println("Max axiom size (split conjunctions): "+result.statements.map(_.size).max)
// 			  println("Cyclic definers left: "+countDefiners(result))
// 			} catch { 
// 			  case _:TimeoutException => 
// 			    println("Timeout exceeded.")
// 			  exec.lastThread.getOrElse(throw new RuntimeException("Not started")).stop()
// 			}
			
// 			println("Finished at "+(new Date()).toString)		      
// 			new File("dlForgetting.log").delete()
// 			Runtime.getRuntime().exec("rm *.log")
// 		      }
		    
// 		      //	      println("Exporting to "+output)
// 		      //	      new OWLExporter().exportOntology(result, new File(output))
// 		      RoleForgetter.clean()
// 		    }
// 		  }
// 		  counter += 1
// 		}		   	      
// 	      }
// 	   }
// 	}
//       } catch { 
// 	case e: OWLOntologyCreationIOException => println("Exception while loading ontology: "+e.toString)
// 	case e: MatchError => e.printStackTrace(); System.exit(1)
// 	case e: java.util.NoSuchElementException => e.printStackTrace(); System.exit(1)
// 	case e: Exception => 
// 	  println("Exception thrown: "+e.toString)
// 	  e.printStackTrace()
//       }
//     }
//   }

// //   def redoFailedExperiments(timeOut: Duration) = { 
// //     val experimentsInOrder = failedExperiments.toSeq.sortBy(_.numberToForget)
      
// //     experimentsInOrder.foreach{ experiment =>
// //       try{ 

// // 	println("\n\n\n\nRedoing with timeout "+timeOut.toString)
// // 	println("Ontology: "+experiment.ontology)
// // 	println("Signature size: "+experiment.signature.size)
	
// // 	var owlOntology = try{ 
// // 	  OWLApiInterface.getOWLOntology(experiment.ontology)
// // 	} catch { 
// // 	  case _:IllegalArgumentException => OWLApiInterface.getOWLOntology(new File(experiment.ontology))
// // 	}
	
// // 	OWLOntologyFilters.restrictToALCH(owlOntology)
	
// // 	val ontology = OWLApiConverter.convert(owlOntology)
	
// // 	val signature = OWLApiInterface.getSignature(owlOntology)
// // 	val interpolantsSignature = signature.filter{ s: OWLEntity => experiment.signature(s.getIRI.getFragment)}
	
// // 	println("Size: "+ontology.size)
// // 	println("Axioms: "+ontology.statements.size)
// // 	println("Max axiom size: "+ontology.statements.map(_.size).max)
// // 	println()
// // 	println("Desired signature: "+interpolantsSignature.map(_.getIRI.getFragment))
// // 	println()
// // 	println("Started at "+(new Date()).toString)
// // 	println()
		      
// // 	try { 
// // 	  val futureResult = future[Ontology]{ 
// // 	    interpolator.uniformInterpolant(owlOntology, interpolantsSignature)
// // 	  }
// // 	  var result = Await.result(futureResult, timeOut)
// // 	  println("Size of the output: "+result.size)
// // 	  println("Number of axioms: "+result.tbox.axioms.size)
// // 	  println("Max axiom size (output): "+result.statements.map(_.size).max)
// // 	  result = DLHelpers.splitConjunctions(result)
// // 	  println("Size of the output (split conjunctions): "+result.size)
// // 	  println("Number of axioms (split conjunctions): "+result.tbox.axioms.size)
// // 	  println("Max axiom size (split conjunctions): "+result.statements.map(_.size).max)
// // 	  println("Cyclic definers left: "+countDefiners(result))
// // 	} catch { 
// // 	  case e: RuntimeException => println("Runtime exception: "+e.getMessage())
// // 	  case e: TimeoutException => 
// // 	    println("Timeout exceeded.")
// // 	    exec.lastThread.getOrElse(throw new RuntimeException("Not started.")).stop()
// // 	  case e: OutOfMemoryError => e.printStackTrace(); println("Stopped process"); System.exit(1)
// // 	}
// // 	(new File("dlForgetting.log")).delete()
// // 	(new File("formulaPreparations.log")).delete()
// // 	println("Finished at "+(new Date()).toString)

// // 	ConceptAndRoleForgetter.clean()
// // //	System.gc()
// //       } catch { 
// // 	case e: OWLOntologyCreationIOException => println("Exception while loading ontology: "+e.toString)
// // 	case e: OutOfMemoryError => e.printStackTrace(); println("Stopped due memory error"); System.exit(1)
// // 	case e: Exception => 
// // 	  println("Exception thrown: "+e.toString)
// // 	e.printStackTrace()
// //       }
// //      }
// //   }


//   def countDefiners(ontology: Ontology) = { 
//     ontology.atomicConcepts.filter(_.startsWith("_D")).size
//   }

//   def main(args: Array[String]): Unit = { 

//     if(args.size==0){ 
//       println("Usage: Experimenter CONFIGURATION [SEED] [CONTINUE] [simulate]")
//       exit(0)
//     }

//     loadConfiguration(new File(args(0)).getAbsoluteFile())
    
//     var simulate = false
//     var seed = (new Date()).getTime()
//     var continue = 0
    
//     if(args.contains("simulate"))
//       simulate = true
    
//     if(args.size>1 && args(1)!="simulate")
//       seed = args(1).toLong

//     if(args.size>2 && args(2)!="simulate")
//       continue = args(2).toInt

//     run(simulate, seed, continue)
//   }
// }
