/**
* NotGoalDesc.java
* author: fm086
* date: 22.07.2008
*
*/

package uk.ac.bham.cs.zas.pddl.goalseffects;

import java.util.Map;
import java.util.Set;

import uk.ac.bham.cs.zas.pddl.domain.ConsistentLiteralSet;
import uk.ac.bham.cs.zas.pddl.domain.FormalArgument;
import uk.ac.bham.cs.zas.pddl.domain.GoalDesc;
import uk.ac.bham.cs.zas.pddl.domain.LiteralInstance;
import uk.ac.bham.cs.zas.pddl.domain.PDDLObject;

public class NotGoalDesc implements GoalDesc {
    
	private final boolean evaluable;
    private GoalDesc negatedGoal;

    public NotGoalDesc(GoalDesc negGoal){
    	this.negatedGoal = negGoal;
    	evaluable = negGoal.isEvaluable();
    }
    
	@Override
	public boolean evaluate(ConsistentLiteralSet literals) {
		return !negatedGoal.evaluate(literals);
	}

	@Override
	public void getLiteralsUsed(Set<LiteralInstance> resultSet) {
        if (!evaluable) {
            throw new IllegalStateException("Attempt to get literals used by non-evaluable goal desc");
        }
        negatedGoal.getLiteralsUsed(resultSet);
	}

	@Override
	public GoalDesc instantiate(Map<FormalArgument, PDDLObject> parameters, Set<PDDLObject> objects) {
        if (evaluable) {
            return this;
        } else {
        	GoalDesc newSub = (GoalDesc) negatedGoal.instantiate(parameters, objects);
        	return new NotGoalDesc(newSub);
        }
	}

	@Override
	public boolean isEvaluable() {
		return evaluable;
	}
	
	@Override
	public String toString(){
		
        return "(not ("+negatedGoal+"))";		
	}

}
