All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.gitlab.chaver.mining.patterns.constraints.AdequateClosure Maven / Gradle / Ivy

There is a newer version: 1.0.1
Show newest version
/*
 * This file is part of io.gitlab.chaver:data-mining (https://gitlab.com/chaver/data-mining)
 *
 * Copyright (c) 2022, IMT Atlantique
 *
 * Licensed under the MIT license.
 *
 * See LICENSE file in the project root for full license information.
 */
package io.gitlab.chaver.mining.patterns.constraints;

import io.gitlab.chaver.mining.patterns.io.Database;
import io.gitlab.chaver.mining.patterns.measure.Measure;
import io.gitlab.chaver.mining.patterns.measure.compute.MeasureComputer;
import lombok.Getter;
import org.chocosolver.memory.IStateInt;
import org.chocosolver.solver.constraints.Propagator;
import org.chocosolver.solver.exception.ContradictionException;
import org.chocosolver.solver.variables.BoolVar;
import org.chocosolver.util.ESat;

import java.util.LinkedList;
import java.util.List;
import java.util.stream.IntStream;

import static io.gitlab.chaver.mining.patterns.measure.compute.MeasureComputerFactory.getMeasureComputer;

/**
 * Given a database D and a set of preserving measures M', the AdequateClosure constraint ensures
 * that x+ is a closed pattern w.r.t. M'
 */
public abstract class AdequateClosure extends Propagator {

    private final BoolVar[] items;
    private final Database database;
    private @Getter final List computers;
    private final int[] freeItems;
    private final IStateInt lastIndexFree;
    private final int[] absentItems; // items instanciated to 0
    private final IStateInt lastIndexAbs;
    private final int firstIndex;
    private int nFree;
    private int nAbs;

    public AdequateClosure(Database database, List measures, BoolVar[] items) {
        super(items);
        this.items = items;
        this.database = database;
        this.computers = new LinkedList<>();
        for (Measure m : measures) {
            computers.add(getMeasureComputer(m, database, getModel()));
        }
        this.freeItems = IntStream.range(0, database.getNbItems()).toArray();
        this.lastIndexFree = getModel().getEnvironment().makeInt(items.length);
        this.firstIndex = database.getNbClass();
        this.absentItems = freeItems.clone();
        this.lastIndexAbs = getModel().getEnvironment().makeInt(firstIndex);
    }

    private boolean isConstant(int i) {
        for (MeasureComputer computer : computers) {
            if (!computer.isConstant(i)) return false;
        }
        return true;
    }

    private boolean isConstant(int i, int j) {
        for (MeasureComputer computer : computers) {
            if (!computer.isConstant(i, j)) return false;
        }
        return true;
    }

    protected void rule3() throws ContradictionException {
        for (int i = nAbs - 1; i >= firstIndex; i--) {
            int idx = absentItems[i];
            for (int j = nFree - 1; j >= firstIndex; j--) {
                int idx2 = freeItems[j];
                if (isConstant(idx, idx2)) {
                    nFree = removeItem(j, nFree, idx2);
                    nAbs = addItem(nAbs, idx2);
                    items[idx2].setToFalse(this);
                }
            }
        }
    }

    public abstract void checkDC() throws ContradictionException;

    @Override
    public void propagate(int evtmask) throws ContradictionException {
        nFree = lastIndexFree.get();
        nAbs = lastIndexAbs.get();
        for (int i = nFree - 1; i >= firstIndex; i--) {
            int idx = freeItems[i];
            if (items[idx].isInstantiated()) {
                nFree = removeItem(i, nFree, idx);
                if (items[idx].isInstantiatedTo(1)) {
                    computeMeasures(idx);
                }
                else {
                    nAbs = addItem(nAbs, idx);
                }
            }
        }
        // fails if exists absent item idx such that m(x+ U {idx}) = m(x+) for all measures
        for (int i = nAbs - 1; i >= firstIndex; i--) {
            int idx = absentItems[i];
            if (isConstant(idx)) fails();
        }
        // all items idx such that m(x U {idx}) = m(x) for all measures are added in the set of present items
        for (int i = nFree - 1; i >= firstIndex; i--) {
            int idx = freeItems[i];
            if (isConstant(idx)) {
                nFree = removeItem(i, nFree, idx);
                items[idx].setToTrue(this);
            }
        }
        checkDC();
        lastIndexFree.set(nFree);
        lastIndexAbs.set(nAbs);
    }

    private void computeMeasures(int idx) {
        for (MeasureComputer computer : computers) {
            computer.compute(idx);
        }
    }

    private int removeItem(int i, int nU, int idx) {
        int lastU = nU - 1;
        freeItems[i] = freeItems[lastU];
        freeItems[lastU] = idx;
        return lastU;
    }

    private int addItem(int nP, int idx) {
        absentItems[nP] = idx;
        return nP + 1;
    }

    @Override
    public ESat isEntailed() {
        return ESat.UNDEFINED;
    }
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy