org.eclipse.agail.genconfgen.CheckAll.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.agail.genconfgen.CheckAll.java

Source

/*********************************************************************
* Copyright (c) 2017-11-28 Christoph Uran (TU Graz)
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/

package org.eclipse.agail.genconfgen;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Properties;
import java.util.concurrent.TimeUnit;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.stream.JsonReader;

public class CheckAll {
    private static String clingoPath = "clingo";
    private static String programPath = "kb.lp";
    private static String userRequirementsDefinitionPath = "user_requirements_definition.json";
    private static String minConflictSetPath = "min_conflict_sets.json";

    public static void main(String[] args) {
        HashSet<ArrayList<String>> allMinConflictSets = new HashSet<ArrayList<String>>();

        // read config file
        String filename = "config-all.properties";
        Properties properties = new Properties();
        try {
            properties.load(new FileReader(filename));
        } catch (IOException e) {
            System.err.println("Could not load the configuration file " + filename + ".");
        }
        clingoPath = properties.getProperty("clingo_path", clingoPath);
        programPath = properties.getProperty("program_path", programPath);
        userRequirementsDefinitionPath = properties.getProperty("user_requirements_definition_path",
                userRequirementsDefinitionPath);
        minConflictSetPath = properties.getProperty("min_conflict_sets_path", minConflictSetPath);

        ClingoExecutor clingoExecutor = new ClingoExecutor(clingoPath, programPath, 1);
        QuickXPlain quickXPlain = new QuickXPlain(clingoExecutor);

        // parse user requirements definition
        ArrayList<UserRequirementDefinition> userRequirements = parseUserRequirementsDefinition();
        System.out.println("Parsed user requirements definition (" + userRequirements.size() + " items)");
        ArrayList<UserRequirementDefinition> dynamicUserRequirements = new ArrayList<UserRequirementDefinition>();
        for (UserRequirementDefinition userRequirementDefinition : userRequirements) {
            if (userRequirementDefinition.getType().equals("dynamic")) {
                dynamicUserRequirements.add(userRequirementDefinition);
            }
        }
        int numOfDynConstraints = dynamicUserRequirements.size();
        System.out.println(dynamicUserRequirements.size() + " of which are dynamic.");
        //      System.out.println(userRequirements.toString());

        int numOfPossibleCombinations = 1;
        for (UserRequirementDefinition dynamicUserRequirement : dynamicUserRequirements) {
            numOfPossibleCombinations *= (dynamicUserRequirement.getPossibleValues().size());
        }
        System.out.println("There are " + numOfPossibleCombinations + " possible combinations");

        int[] currentPositions = new int[numOfDynConstraints];
        int[] dynSizes = new int[numOfDynConstraints];
        for (int i = 0; i < currentPositions.length; i++) {
            currentPositions[i] = -1;
            dynSizes[i] = dynamicUserRequirements.get(i).getPossibleValues().size() - 1;
        }

        //      dynSizes = new int[] {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};

        System.out.println("Current positions: " + Arrays.toString(currentPositions));
        System.out.println("Sizes of dynamic user requirements: " + Arrays.toString(dynSizes));

        long startTime = System.currentTimeMillis();
        int iteration = 1;

        boolean finished = false;
        while (!finished) {
            printProgress(startTime, numOfPossibleCombinations, iteration);

            finished = !shift(currentPositions, dynSizes, currentPositions.length - 1);
            //         System.out.println("Current positions: " + Arrays.toString(currentPositions));

            ArrayList<String> constraints = new ArrayList<String>();
            int dynUserRequirementIndex = 0;

            for (UserRequirementDefinition userRequirementDefinition : userRequirements) {
                String constraint = "";
                if (userRequirementDefinition.getType().equals("dynamic")) {
                    if (currentPositions[dynUserRequirementIndex] != -1) {
                        constraint = String.format(userRequirementDefinition.getConstraint(),
                                dynamicUserRequirements.get(dynUserRequirementIndex).getPossibleValues()
                                        .get(currentPositions[dynUserRequirementIndex]));
                    }
                    dynUserRequirementIndex++;
                } else {
                    constraint = userRequirementDefinition.getConstraint();
                }
                constraints.add(constraint);
            }
            //         System.out.println(constraints);

            //         if (!hasKnownConflict(constraints, allMinConflictSets) || !clingoExecutor.isConsistent(constraints)) {
            if (!clingoExecutor.isConsistent(constraints)) {
                //            System.out.println("Inconsistent: " + constraints);
                ArrayList<String> minConflictSet = quickXPlain.quickXPlain(constraints, "");
                //            System.out.println("Minimal conflict set: " + minConflictSet);
                if (allMinConflictSets.add(minConflictSet)) {
                    System.out.println();
                    System.out.println(
                            "New minimal conflict set (now " + allMinConflictSets.size() + "): " + minConflictSet);
                    writeMinConflictsToFile(allMinConflictSets);
                }
            }
            iteration++;
        }
    }

    // from https://stackoverflow.com/a/39257969/480370
    private static void printProgress(long startTime, int total, int current) {
        long eta = current == 0 ? 0 : (total - current) * (System.currentTimeMillis() - startTime) / current;

        String etaHms = current == 0 ? "N/A"
                : String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(eta),
                        TimeUnit.MILLISECONDS.toMinutes(eta) % TimeUnit.HOURS.toMinutes(1),
                        TimeUnit.MILLISECONDS.toSeconds(eta) % TimeUnit.MINUTES.toSeconds(1));

        StringBuilder string = new StringBuilder(140);
        int percent = (int) (current * 100 / total);
        string.append('\r')
                .append(String.join("",
                        Collections.nCopies(percent == 0 ? 2 : 2 - (int) (Math.log10(percent)), " ")))
                .append(String.format(" %d%% [", percent))
                .append(String.join("", Collections.nCopies(percent, "="))).append('>')
                .append(String.join("", Collections.nCopies(100 - percent, " "))).append(']')
                .append(String.join("",
                        Collections.nCopies((int) (Math.log10(total)) - (int) (Math.log10(current)), " ")))
                .append(String.format(" %d/%d, ETA: %s", current, total, etaHms));

        System.out.print(string);
    }

    private static boolean shift(int[] currentPositions, int[] dynSizes, int index) {
        while (index >= -1) {
            if (currentPositions[index] < dynSizes[index]) {
                currentPositions[index]++;
                return true;
            } else {
                index--;
                for (int i = index + 1; i < currentPositions.length; i++) {
                    currentPositions[i] = -1;
                }
            }
        }
        return false;
    }

    private static ArrayList<UserRequirementDefinition> parseUserRequirementsDefinition() {
        ArrayList<UserRequirementDefinition> userRequirements = new ArrayList<UserRequirementDefinition>();

        try {
            JsonReader reader = new JsonReader(new FileReader(userRequirementsDefinitionPath));
            reader.beginObject();
            reader.nextName();
            UserRequirementDefinition[] userRequirementsArray = (new Gson()).fromJson(reader,
                    UserRequirementDefinition[].class);
            reader.close();

            for (int i = 0; i < userRequirementsArray.length; i++) {
                userRequirements.add(userRequirementsArray[i]);
            }
        } catch (FileNotFoundException e) {
            System.err.println("Could not read from file " + userRequirementsDefinitionPath);
            e.printStackTrace();
            return new ArrayList<UserRequirementDefinition>();
        } catch (IOException e) {
            System.err.println("Could not close file " + userRequirementsDefinitionPath);
            e.printStackTrace();
        }

        return userRequirements;
    }

    private static void writeMinConflictsToFile(HashSet<ArrayList<String>> allMinConflictSets) {
        Writer writer = null;
        Gson gsonWriter = new GsonBuilder().setPrettyPrinting().create();
        try {
            writer = new FileWriter(minConflictSetPath);
            gsonWriter.toJson(allMinConflictSets, writer);
            //         System.out.println("Wrote all known minimal conflict sets to the specified file.");
        } catch (IOException e) {
            System.err.println("Could not open file " + minConflictSetPath + " to save minimal conflict sets");
            e.printStackTrace();
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                    System.err.println("Could not close file " + minConflictSetPath);
                    e.printStackTrace();
                }
            }
        }
    }

    //   private static boolean hasKnownConflict(ArrayList<String> newIndividualConstraints, HashSet<ArrayList<String>> allMinConflictSets) {
    //      if (getKnownConflict(newIndividualConstraints, allMinConflictSets) == null) {
    //         return false;
    //      } else {
    //         return true;
    //      }
    //   }
    //   
    //   private static ArrayList<String> getKnownConflict(ArrayList<String> constraints, HashSet<ArrayList<String>> allMinConflictSets) {
    //      for (ArrayList<String> currentConflictSet : allMinConflictSets) {
    //         if (constraints.containsAll(currentConflictSet)) {
    //            return currentConflictSet;
    //         }
    //      }
    //      
    //      return null;
    //   }

}