package de.renew.net.inscription.arc;

import de.renew.net.SimulatablePlaceInstance;
import de.renew.net.TokenReserver;
import de.renew.unify.Variable;


/**
 * An InhibitorArcBinder binds the variable inscribed on an inhibitor arc and provides the inhibitor arc's functionality
 * through its implementation of the {@link #possible} and {@link #remove} methods. Through them, binding can only
 * succeed if the inscription variable is bound to a token that isn't contained in the inhibitor
 * arc's place instance.
 */
public class InhibitorArcBinder extends ArcRemoveBinder {
    /**
     * The constructor for InhibitorArcBinder.
     *
     * @param variable the {@code Variable} that will be bound
     * @param placeInstance the place instance that is connected to the inhibitor arc
     */
    protected InhibitorArcBinder(Variable variable, SimulatablePlaceInstance placeInstance) {
        super(variable, placeInstance);
    }

    @Override
    protected boolean mayBind() {
        return true;
    }

    @Override
    protected boolean possible(TokenReserver reserver, Object token) {
        return !getPlaceInstance().containsTestableToken(token);
    }

    @Override
    protected boolean remove(TokenReserver reserver, Object token) {
        return possible(reserver, token);
    }

    @Override
    protected void unremove(TokenReserver reserver, Object token) {
        // Nothing to do. No tokens are moved.
    }
}