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

org.key_project.slicing.SlicingExtension Maven / Gradle / Ivy

Go to download

Computiation of the proof core (the essential rule applications to close a proof)

The newest version!
/* This file is part of KeY - https://key-project.org
 * KeY is licensed under the GNU General Public License Version 2
 * SPDX-License-Identifier: GPL-2.0-only */
package org.key_project.slicing;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Nonnull;
import javax.swing.*;

import de.uka.ilkd.key.core.KeYMediator;
import de.uka.ilkd.key.core.KeYSelectionEvent;
import de.uka.ilkd.key.core.KeYSelectionListener;
import de.uka.ilkd.key.gui.MainWindow;
import de.uka.ilkd.key.gui.extension.api.ContextMenuAdapter;
import de.uka.ilkd.key.gui.extension.api.ContextMenuKind;
import de.uka.ilkd.key.gui.extension.api.KeYGuiExtension;
import de.uka.ilkd.key.gui.extension.api.TabPanel;
import de.uka.ilkd.key.gui.settings.SettingsProvider;
import de.uka.ilkd.key.logic.PosInOccurrence;
import de.uka.ilkd.key.pp.PosInSequent;
import de.uka.ilkd.key.proof.Node;
import de.uka.ilkd.key.proof.Proof;
import de.uka.ilkd.key.proof.event.ProofDisposedEvent;
import de.uka.ilkd.key.proof.event.ProofDisposedListener;

import org.key_project.slicing.graph.GraphNode;
import org.key_project.slicing.ui.ShowCreatedByAction;
import org.key_project.slicing.ui.ShowGraphAction;
import org.key_project.slicing.ui.SlicingLeftPanel;

/**
 * Proof slicing extension.
 * For more details see the user
 * guide.
 *
 * @author Arne Keller
 */
@KeYGuiExtension.Info(name = "Slicing",
    description = "Author: Arne Keller ",
    experimental = false,
    optional = true,
    priority = 9001)
public class SlicingExtension implements KeYGuiExtension,
        KeYGuiExtension.ContextMenu,
        KeYGuiExtension.Startup,
        KeYGuiExtension.LeftPanel,
        KeYGuiExtension.Settings,
        KeYSelectionListener,
        ProofDisposedListener {
    /**
     * Collection of dependency trackers attached to proofs.
     */
    public final Map trackers = new IdentityHashMap<>();
    /**
     * The left panel inserted into the GUI.
     */
    private SlicingLeftPanel leftPanel = null;
    /**
     * If set to true, the rule application de-duplication algorithm is automatically limited to
     * the "safe mode" for the next loaded proof.
     */
    private boolean enableSafeModeForNextProof = false;

    /**
     * The context menu adapter used by the extension.
     */
    private final ContextMenuAdapter adapter = new ContextMenuAdapter() {
        @Override
        public List getContextActions(
                KeYMediator mediator, ContextMenuKind kind, PosInSequent pos) {

            DependencyTracker tracker = trackers.get(mediator.getSelectedProof());
            if (tracker == null
                    || pos == null
                    || pos.getPosInOccurrence() == null
                    || pos.getPosInOccurrence().topLevel() == null
                    || mediator.getSelectedNode() == null) {
                return List.of();
            }
            Node currentNode = mediator.getSelectedNode();
            Proof currentProof = currentNode.proof();

            PosInOccurrence topLevel = pos.getPosInOccurrence().topLevel();
            Node node = tracker.getNodeThatProduced(currentNode, topLevel);
            if (node == null) {
                return List.of();
            }
            List list = new ArrayList<>();
            list.add(new ShowCreatedByAction(MainWindow.getInstance(), node));
            GraphNode graphNode = tracker.getDependencyGraph()
                    .getGraphNode(currentProof, currentNode.getBranchLocation(), topLevel);
            if (graphNode != null) {
                list.add(new ShowGraphAction(MainWindow.getInstance(), tracker, graphNode));
                // debugging dialog:
                // list.add(new ShowNodeInfoAction(MainWindow.getInstance(), tracker, graphNode));
            }
            return list;
        }
    };

    @Nonnull
    @Override
    public List getContextActions(@Nonnull KeYMediator mediator,
            @Nonnull ContextMenuKind kind,
            @Nonnull Object underlyingObject) {
        return adapter.getContextActions(mediator, kind, underlyingObject);
    }

    @Override
    public void selectedProofChanged(KeYSelectionEvent e) {
        createTrackerForProof(e.getSource().getSelectedProof());
    }

    @Override
    public void init(MainWindow window, KeYMediator mediator) {
        mediator.addKeYSelectionListener(this);
        mediator.registerProofLoadListener(this::createTrackerForProof);
    }

    private void createTrackerForProof(Proof newProof) {
        trackers.computeIfAbsent(newProof, proof -> {
            if (proof == null) {
                return null;
            }
            proof.addProofDisposedListener(this);
            DependencyTracker tracker = new DependencyTracker(proof);
            if (leftPanel != null) {
                proof.addRuleAppListener(e -> leftPanel.ruleAppliedOnProof(proof, tracker));
                proof.addProofTreeListener(leftPanel);
                if (enableSafeModeForNextProof) {
                    SlicingSettingsProvider.getSlicingSettings()
                            .deactivateAggressiveDeduplicate(proof);
                    enableSafeModeForNextProof = false;
                }
            }
            return tracker;
        });
    }

    @Nonnull
    @Override
    public Collection getPanels(
            @Nonnull MainWindow window, @Nonnull KeYMediator mediator) {
        if (leftPanel == null) {
            leftPanel = new SlicingLeftPanel(mediator, this);
            mediator.addKeYSelectionListener(leftPanel);
        }
        return Collections.singleton(leftPanel);
    }

    @Override
    public void proofDisposing(ProofDisposedEvent e) {
        trackers.put(e.getSource(), null);
        trackers.remove(e.getSource());
        if (leftPanel != null) {
            leftPanel.proofDisposed(e.getSource());
        }
    }

    @Override
    public void proofDisposed(ProofDisposedEvent e) {

    }

    @Override
    public SettingsProvider getSettings() {
        return new SlicingSettingsProvider();
    }

    /**
     * Activate the de-duplication safe mode for the next loaded proof.
     */
    public void enableSafeModeForNextProof() {
        this.enableSafeModeForNextProof = true;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy