/*
 * Copyright The Sett Ltd, 2005 to 2014.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.thesett.aima.logic.fol.wam.debugger;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.LinkedList;
import java.util.List;

import com.thesett.aima.logic.fol.wam.machine.WAMMemoryLayout;
import com.thesett.common.util.event.EventListenerSupport;

/**
 * InternalMemoryLayoutBean represents {@link WAMMemoryLayout} as a Java bean, and adds the ability to attach a
 * {@link PropertyChangeListener} to it. The change listener will be notified when any registers or flags change value.
 *
 *

CRC Card

 *
 Responsibilities  Collaborations
 *
 Provide change notification on registers and flags describing the memory layout.
 *

 *
 * @author Rupert Smith
 */
public class InternalMemoryLayoutBean extends WAMMemoryLayout implements RegisterModel
{
    /** Defines the names of the machine registers. */
    private static final String[] REGISTER_NAMES =
        new String[]
        {
            "regBase", "regSize", "heapBase", "heapSize", "stackBase", "stackSize", "trailBase", "trailSize", "pdlBase",
            "pdlSize"
        };

    /** Defines the names of the machine flags. */
    public static final String[] FLAG_NAMES = new String[] {};

    /** Holds any property change listeners to notify of register value changes. */
    private final EventListenerSupport<PropertyChangeListener> listeners = new EventListenerSupport<PropertyChangeListener>();

    /**
     * Creates an instance of the WAM memory layout.
     *
     * @param regBase   The start of the register file within the machines data area.
     * @param regSize   The size of the register file.
     * @param heapBase  The start of the within the machines data area.
     * @param heapSize  The size of the heap.
     * @param stackBase the start of the within the machines data area.
     * @param stackSize the size of the stack.
     * @param trailBase the start of the within the machines data area.
     * @param trailSize the size of the trail.
     * @param pdlBase   The start of the within the machines data area.
     * @param pdlSize   The size of the pdl.
     */
    public InternalMemoryLayoutBean(int regBase, int regSize, int heapBase, int heapSize, int stackBase, int stackSize,
        int trailBase, int trailSize, int pdlBase, int pdlSize)
    {
        super(regBase, regSize, heapBase, heapSize, stackBase, stackSize, trailBase, trailSize, pdlBase, pdlSize);
    }

    /**
     * Establishes a PropertyChangeListener to notify of changes to the register file or flags.
     *
     * @param listener A PropertyChangeListener to notify of changes to the register file or flags.
     */
    public void addPropertyChangeListener(PropertyChangeListener listener)
    {
        listeners.addListener(listener);
    }

    /**
     * Updates the layout register file, with a new set of layout registers.
     *
     * @param layout The new layout register values.
     */
    public void updateRegisters(WAMMemoryLayout layout)
    {
        List<PropertyChangeEvent> changes = delta(this, layout);

        regBase = layout.regBase;
        regSize = layout.regSize;
        heapBase = layout.heapBase;
        heapSize = layout.heapSize;
        stackBase = layout.stackBase;
        stackSize = layout.stackSize;
        trailBase = layout.trailBase;
        trailSize = layout.trailSize;
        pdlBase = layout.pdlBase;
        pdlSize = layout.pdlSize;

        notifyChanges(changes);
    }

    /** Provides the start of the register file within the machines data area. */
    public int getRegBase()
    {
        return regBase;
    }

    /** Provides the size of the register file. */
    public int getRegSize()
    {
        return regSize;
    }

    /** Provides the start of the within the machines data area. */
    public int getHeapBase()
    {
        return heapBase;
    }

    /** Provides the size of the heap. */
    public int getHeapSize()
    {
        return heapSize;
    }

    /** Provides the start of the within the machines data area. */
    public int getStackBase()
    {
        return stackBase;
    }

    /** Provides the size of the stack. */
    public int getStackSize()
    {
        return stackSize;
    }

    /** Provides the start of the within the machines data area. */
    public int getTrailBase()
    {
        return trailBase;
    }

    /** Provides the size of the trail. */
    public int getTrailSize()
    {
        return trailSize;
    }

    /** Provides the start of the within the machines data area. */
    public int getPdlBase()
    {
        return pdlBase;
    }

    /** Provides the size of the pdl. */
    public int getPdlSize()
    {
        return pdlSize;
    }

    /** {@inheritDoc} */
    public String[] getRegisterNames()
    {
        return REGISTER_NAMES;
    }

    /** {@inheritDoc} */
    public String[] getFlagNames()
    {
        return FLAG_NAMES;
    }

    /** {@inheritDoc} */
    public int getRegisterSizeBytes(String name)
    {
        return 4;
    }

    /** {@inheritDoc} */
    public byte[] getRegister(String name)
    {
        return new byte[0];
    }

    /** {@inheritDoc} */
    public boolean getFlag(String name)
    {
        return false;
    }

    /**
     * Compares the current register file, with a new set, and creates a list property change notifications for any that
     * have changed value.
     *
     * @param newRegisters The new register values.
     */
    private List<PropertyChangeEvent> delta(WAMMemoryLayout oldRegisters, WAMMemoryLayout newRegisters)
    {
        List<PropertyChangeEvent> result = new LinkedList<PropertyChangeEvent>();

        if (oldRegisters.regBase != newRegisters.regBase)
        {
            result.add(new PropertyChangeEvent(this, "regBase", oldRegisters.regBase, newRegisters.regBase));
        }

        if (oldRegisters.regSize != newRegisters.regSize)
        {
            result.add(new PropertyChangeEvent(this, "regSize", oldRegisters.regSize, newRegisters.regSize));
        }

        if (oldRegisters.heapBase != newRegisters.heapBase)
        {
            result.add(new PropertyChangeEvent(this, "heapBase", oldRegisters.heapBase, newRegisters.heapBase));
        }

        if (oldRegisters.heapSize != newRegisters.heapSize)
        {
            result.add(new PropertyChangeEvent(this, "heapSize", oldRegisters.heapSize, newRegisters.heapSize));
        }

        if (oldRegisters.stackBase != newRegisters.stackBase)
        {
            result.add(new PropertyChangeEvent(this, "stackBase", oldRegisters.stackBase, newRegisters.stackBase));
        }

        if (oldRegisters.stackSize != newRegisters.stackSize)
        {
            result.add(new PropertyChangeEvent(this, "stackSize", oldRegisters.stackSize, newRegisters.stackSize));
        }

        if (oldRegisters.trailBase != newRegisters.trailBase)
        {
            result.add(new PropertyChangeEvent(this, "trailBase", oldRegisters.trailBase, newRegisters.trailBase));
        }

        if (oldRegisters.trailSize != newRegisters.trailSize)
        {
            result.add(new PropertyChangeEvent(this, "trailSize", oldRegisters.trailSize, newRegisters.trailSize));
        }

        if (oldRegisters.pdlBase != newRegisters.pdlBase)
        {
            result.add(new PropertyChangeEvent(this, "pdlBase", oldRegisters.pdlBase, newRegisters.pdlBase));
        }

        if (oldRegisters.pdlSize != newRegisters.pdlSize)
        {
            result.add(new PropertyChangeEvent(this, "pdlSize", oldRegisters.pdlSize, newRegisters.pdlSize));
        }

        return result;
    }

    /**
     * Fires off a list of property change events to any interested listeners.
     *
     * @param changes The list of property changes to fire off.
     */
    private void notifyChanges(Iterable<PropertyChangeEvent> changes)
    {
        List<PropertyChangeListener> activeListeners = listeners.getActiveListeners();

        if (activeListeners != null)
        {
            for (PropertyChangeListener listener : activeListeners)
            {
                for (PropertyChangeEvent event : changes)
                {
                    listener.propertyChange(event);
                }
            }
        }
    }
}


/**
 * Copyright 2010 Bazaarvoice, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @author J. Ryan Stinnett (ryan.stinnett@bazaarvoice.com)
 */

package com.bazaarvoice.jless.ast.node;

import com.bazaarvoice.jless.ast.util.NodeTreeUtils;
import com.bazaarvoice.jless.ast.visitor.NodeAdditionVisitor;
import com.bazaarvoice.jless.ast.visitor.NodeNavigationVisitor;

public class VariableReferenceNode extends LeafNode {

    private String _name;

    public VariableReferenceNode(String name) {
        _name = name;
    }

    /**
     * Search up the scope tree to locate the variable's value. The parser has already verified that
     * the variable is defined.
     */
    public String getValue() {
        for (ScopeNode scope = NodeTreeUtils.getParentScope(this); scope != null; scope = NodeTreeUtils.getParentScope(scope)) {
            ExpressionGroupNode value = scope.getVariable(_name);
            if (value == null) {
                continue;
            }

            return value.toString();
        }

        return _name; // Unable to find the variable's value, return the name for now (helpful for debugging)
    }

    @Override
    protected boolean add(NodeAdditionVisitor visitor) {
        return visitor.add(this);
    }

    @Override
    protected boolean visit(NodeNavigationVisitor visitor) {
        return visitor.visit(this);
    }

    @Override
    protected boolean visitInvisible(NodeNavigationVisitor visitor) {
        return visitor.visitInvisible(this);
    }
}


/*
 * Copyright The Sett Ltd, 2005 to 2014.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.thesett.aima.search.impl.bidirectional;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;

import com.thesett.aima.search.Operator;
import com.thesett.aima.search.QueueBasedSearchMethod;
import com.thesett.aima.search.RepeatedStateFilter;
import com.thesett.aima.search.SearchNode;
import com.thesett.aima.search.SearchNotExhaustiveException;
import com.thesett.aima.search.Successor;
import com.thesett.aima.search.Traversable;
import com.thesett.aima.search.spi.PathJoinAlgorithm;
import com.thesett.common.error.NotImplementedException;
import com.thesett.common.util.logic.UnaryPredicate;

/**
 * BaseBiDirectionalQueueSearch provides a base implementation for deriving new bidirectional searches from by providing
 * different queue implementations for the forward and reverse portions of the search. For example using a LIFO queue
 * generates depth first search and a FIFO queue generates breadth first. Heuristic searches can easily be implemented
 * by using priority queues with ordering predicates based on a heuristic evaluation.
 *
 *
The search proceeds by taking the next element of the forward search fringe and testing to see if it matches one
 * element of the reverse fringe. It then expands the forward fringe with the successor nodes if no match is found. Then
 * it takes the next element of the reverse fringe and does the same matching and expanding process against the forward
 * fringe. The states need to be hashable in order to make the fringe matching efficient.
 *
 *
Once a match between the forward and reverse fringes has been found it then walks backwards along the node found
 * on the reverse fringe adding all its states and operations to the forward search path. This class implements a
 * standard algorithm for doing this. It assumes that the state space being searched by both halfs of the search is over
 * the same states. It also assumes that the applied operations in the reverse search node have already been reverse.
 * For example, if the search space was the eight tiles game then the moves stored in the reverse half of the search
 * would have to be stored in the reverse direction to that in which they are applied when really playing the game
 * backwards. This means that two implementations of {@link com.thesett.aima.search.TraversableState} are needed, one
 * that gives its operators reversed.
 *
 *
It is possible to supply an alternative path joining algorithm that does know how to reverse the operators. Set
 * this algorithm by calling the {@link #setPathJoinAlgorithm} method. This is an alternative to writing two
 * implementatios of {@link com.thesett.aima.search.TraversableState}
 *
 *

CRC Card

 *
 Responsibilities  Collaborations
 *
 Bidirectional search state space using specified queue implementations  {@link SearchNode}
 *

 *
 * @author Rupert Smith
 * @todo   At least one of the directions ought to be a breadth first search. Provide some explanation of this from the
 *         literature as well as some other saliant information about bi-directional searches.
 */
public class BaseBiDirectionalQueueSearch<O, T extends Traversable<O>> implements QueueBasedSearchMethod<O, T>
{
    /** The queue used to control the forward search order. */
    protected Queue<SearchNode<O, T>> forwardQueue;

    /** The queue used to control the reverse search order. */
    protected Queue<SearchNode<O, T>> reverseQueue;

    /** Used to maintain a map of states to search nodes to those states on the forward fringe. */
    protected Map<T, SearchNode<O, T>> forwardFringe;

    /** Used to maintain a map of states to search nodes to those states on the reverse fringe. */
    protected Map<T, SearchNode<O, T>> reverseFringe;

    /** Holds a reference to the start node. */
    protected SearchNode<O, T> startNode;

    /** Holds a reference to the goal node. */
    protected SearchNode<O, T> goalNode;

    /** Holads the goal predicate. */
    protected UnaryPredicate<T> goalPredicate;

    /** Used to hold a reference to an alternative path join algorithm. */
    PathJoinAlgorithm<O, T> pathJoiner;

    /**
     * Constructor that takes an initial search node, a goal node, a forward and a reverse search queue implementation.
     * Different kinds of searches can be instantiated by passing different queue and search nodeimplementations to this
     * constructor.
     *
     * @param startNode    The search start point as a search node.
     * @param goalNode     The search end point as a search node.
     * @param forwardQueue The queue implementation for the forward search.
     * @param reverseQueue The queue implmenetation for the reverse search.
     */
    public BaseBiDirectionalQueueSearch(SearchNode<O, T> startNode, SearchNode<O, T> goalNode,
        Queue<SearchNode<O, T>> forwardQueue, Queue<SearchNode<O, T>> reverseQueue)
    {
        this.forwardQueue = forwardQueue;
        this.reverseQueue = reverseQueue;
        this.startNode = startNode;
        this.goalNode = goalNode;

        // Clear both fringe sets
        forwardFringe = new HashMap<T, SearchNode<O, T>>();
        reverseFringe = new HashMap<T, SearchNode<O, T>>();

        // Add just the start node to the forward queue and fringe set to begin with
        forwardQueue.add(startNode);
        forwardFringe.put(startNode.getState(), startNode);

        // Add just the goal node to the reverse queue and fringe set to begin with
        reverseQueue.add(goalNode);
        reverseFringe.put(goalNode.getState(), goalNode);
    }

    /**
     * Attaches the specified repeated state filtering strategy to the search algorithm.
     *
     * @param filter The repeated state filter to prune the search space with.
     */
    public void setRepeatedStateFilter(RepeatedStateFilter filter)
    {
        throw new NotImplementedException();
    }

    /**
     * Sets the maximum number of search steps that a search method may take. If it fails to find a solution before this
     * number of steps has been reached its {@link #findGoalPath} method should fail and return null. What exactly
     * constitutes a single step, and the granularity of the step size, is open to different interpretation by different
     * search algorithms. The guideline is that this is the maximum number of states on which the
     * {@link com.thesett.aima.search.GoalState#isGoal} test should be performed.
     *
     * @param max the maximum number of states to goal test. If this is zero or less then the maximum number of steps
     *            will not be checked for.
     */
    public void setMaxSteps(int max)
    {
        throw new NotImplementedException();
    }

    /**
     * Adds a start state to the search. Many search algorithms will only accept a single start state in which case the
     * most recent call to this method is taken as the definition of the single start state to use. Some search
     * algorithms may take multiple start states in which case successive calls to this method should be used to
     * establish all the start states.
     *
     * @param startState The start state to add to the collection of start states to begin the search with.
     */
    public void addStartState(T startState)
    {
        throw new NotImplementedException();
    }

    /**
     * Some search algorithms may accept definitions of the goal state in which case the most recent call to this method
     * is taken as the definition of the goal state. In some searches the goal state is not known in advance, in others
     * the purpose of the search is to find a path from the start to the goal. If the search algorithm does not accept a
     * goal state it should throw an exception indicating that this method is not supported by that algorithm.
     *
     *

     *
Note that the {@link com.thesett.aima.search.GoalState} interface itself defines the method
     * {@link com.thesett.aima.search.GoalState#isGoal} which tests if a state is a goal state. It is therefore not
     * necessary to call this method to set goal states where the goal definition is defined already in the states.
     * Setting goal states through this method, when it is supported by an algorithm overrides the goal definition in
     * the states themselves.
     *
     * @param  unaryPredicate The goal predicate.
     *
     * @throws UnsupportedOperationException if the search algorithm does not accept goal states.
     */
    public void setGoalPredicate(UnaryPredicate<T> unaryPredicate) throws UnsupportedOperationException
    {
        this.goalPredicate = unaryPredicate;
    }

    /** Resets the search, clearing out the queue and setting it to contain just the start state nodes. */
    public void reset()
    {
        throw new NotImplementedException();
    }

    /**
     * Implementation of the general bi-dircetional search. The search alternated between taking a forward and a reverse
     * step.
     *
     * @return The first {@link SearchNode} corresponding to a goal state that is found or null if none can be found
     *         after exhaustive searching.
     *
     * @throws SearchNotExhaustiveException If the search stops before finding a solution or exhausting the search
     *                                      space. Different search algorithms may fail for different reasons but in
     *                                      particular it it is worth noting that if the maximum number of steps is
     *                                      reached without exhausting the search space this will cause an exception to
     *                                      be thrown rather than for this method to return null.
     */
    public SearchNode<O, T> findGoalPath() throws SearchNotExhaustiveException
    {
        // Keep running until the queue becomes empty or a goal state is found
        while (!forwardQueue.isEmpty() || !reverseQueue.isEmpty())
        {
            // Only run the forward step of the search if the forward queue is not empty
            if (!forwardQueue.isEmpty())
            {
                // Extract the next node from the forward queue
                SearchNode<O, T> currentForwardNode = forwardQueue.remove();

                // Remove this node from the forward fringe map as it will soon be replaced by more fringe members
                forwardFringe.remove(currentForwardNode.getState());

                // Check the reverse fringe against the next forward node for a match.
                if (reverseFringe.containsKey(currentForwardNode.getState()))
                {
                    // A path from start to the goal has been found. Walk backwards along the reverse path adding all
                    // nodes encountered to the forward path until the goal is reached.
                    return joinBothPaths(currentForwardNode, reverseFringe.get(currentForwardNode.getState()));
                }

                // There was no match so a path to the goal has not been found
                else
                {
                    // Get all of the successor states to the current node
                    Queue<SearchNode<O, T>> newStates = new LinkedList<SearchNode<O, T>>();

                    currentForwardNode.expandSuccessors(newStates, false);

                    // Expand all the successors to the current forward node into the buffer to be searched.
                    forwardQueue.addAll(newStates);

                    // Also add all the successors to the current forward fringe map.
                    for (SearchNode<O, T> nextSearchNode : newStates)
                    {
                        forwardFringe.put(nextSearchNode.getState(), nextSearchNode);
                    }
                }
            }

            // Only run the reverse step of the search if the reverse queue is not empty
            if (!reverseQueue.isEmpty())
            {
                // Extract the next node from the reverse queue
                SearchNode<O, T> currentReverseNode = reverseQueue.remove();

                // Remove this node from the reverse fringe set as it will soon be replaced by more fringe members
                reverseFringe.remove(currentReverseNode.getState());

                // Check the forward fringe against the next reverse node for a match.
                if (forwardFringe.containsKey(currentReverseNode.getState()))
                {
                    // A path from start to goal has been found.
                    // Walk backwards along the reverse path adding all nodes encountered to the foward path until the
                    // goal is reached.
                    return joinBothPaths(forwardFringe.get(currentReverseNode.getState()), currentReverseNode);
                }

                // There was no match so a path to the goal has not been found
                else
                {
                    // Get all of the successor states to the current node (really predecessor state)
                    Queue<SearchNode<O, T>> newStates = new LinkedList<SearchNode<O, T>>();

                    currentReverseNode.expandSuccessors(newStates, false);

                    // Expand all the successors to the current reverse node into the reverse buffer to be searched.
                    reverseQueue.addAll(newStates);

                    // Add all the successors to the current reverse fringe set
                    for (SearchNode<O, T> nextSearchNode : newStates)
                    {
                        reverseFringe.put(nextSearchNode.getState(), nextSearchNode);
                    }
                }
            }
        }

        // No goal state was found so return null
        return null;
    }

    /**
     * Perform the search. This can be called multiple times to get successive results where more than one goal can be
     * found, if the algorithm supports this. In this case it should return null once no more goals can be found.
     *
     * @return The first state corresponding to a goal state that is found or null if none can be found after exhaustive
     *         searching. A return value of null should really mean that exhaustive searching has been completed rather
     *         than some premature termination condition being reached. See the comment below about the
     *         SearchNotExhaustiveException.
     *
     * @throws SearchNotExhaustiveException If the search stops before finding a solution or exhausting the search
     *                                      space. Different search algorithms may fail for different reasons but in
     *                                      particular it it is worth noting that if the maximum number of steps is
     *                                      reached without exhausting the search space this will cause an exception to
     *                                      be thrown rather than for this method to return null.
     */
    public T search() throws SearchNotExhaustiveException
    {
        SearchNode<O, T> path = findGoalPath();

        if (path != null)
        {
            return path.getState();
        }
        else
        {
            return null;
        }
    }

    /**
     * Sets an alternative path joining algorithm to use when a match is found between the forward and reverse portions
     * of the search.
     *
     * @param joiner The path join algorithm to use to combine the forward and reverse paths.
     */
    public void setPathJoinAlgorithm(PathJoinAlgorithm<O, T> joiner)
    {
        // Keep the path joining algorithm
        pathJoiner = joiner;
    }

    /**
     * Once a match has been found between the forward and reverse fringes of the search a path is known to exist from
     * the start to the goal. The path is not complete at this stage because it remains to reverse all of the steps in
     * the backward half of the path and add them to the forward half of the path to produce the complete forward path
     * from start to the goal.
     *
     *
This method implements a standard algorithm for doing this. It assumes that the state space being searched by
     * both halfs of the search is over the same states. It also assumes that the applied operations in the reverse
     * search node have already been reverse. For example, if the search space was the eight tiles game then the moves
     * stored in the reverse half of the search would have to be stored in the reverse direction to that in which they
     * are applied when really playing the game backwards. This means that two implementations of
     * {@link com.thesett.aima.search.TraversableState} are needed, one that gives its operators reversed.
     *
     *
It is possible to supply an alternative path joining algorithm that does know how to reverse the operators.
     * Set this in this search algorithm by calling the {@link #setPathJoinAlgorithm} method. This is an alternative to
     * writing two implementatios of {@link com.thesett.aima.search.TraversableState}
     *
     * @param  forwardPath a search node for the forward portion of the goal path
     * @param  reversePath a search node for the reverse portion of the goal path
     *
     * @return a search node corresponding to the path right from start to goal
     *
     * @throws SearchNotExhaustiveException If the node implementation does not allow new nodes to be created from old.
     *                                      See the {@link SearchNode#makeNode} method for more information.
     */
    private SearchNode<O, T> joinBothPaths(SearchNode<O, T> forwardPath, SearchNode<O, T> reversePath)
        throws SearchNotExhaustiveException
    {
        // Check if an alternative path join algorithm has been set and delegate to it if so
        if (pathJoiner != null)
        {
            return pathJoiner.joinBothPaths(forwardPath, reversePath);
        }

        // No alternative path join algorithm has been supplied so use this default one
        else
        {
            // Used to hold the current position along the reverse path of search nodes
            SearchNode<O, T> currentReverseNode = reversePath;

            // Used to hold the current position along the forward path of search nodes
            SearchNode<O, T> currentForwardNode = forwardPath;

            // Loop over all nodes in the reverse path checking if the current reverse node is the
            // goal state to terminate on.
            while (!goalPredicate.evaluate(currentReverseNode.getState()))
            {
                // Create a new forward node from the parent state of the current reverse node, the current reverse
                // nodes applied operation and cost, and an increment of one to the path depth
                SearchNode<O, T> reverseParentNode = currentReverseNode.getParent();
                T state = currentReverseNode.getParent().getState();
                Operator<O> operation = currentReverseNode.getAppliedOp();
                float cost = currentReverseNode.getPathCost() - reverseParentNode.getPathCost();

                currentForwardNode = currentForwardNode.makeNode(new Successor<O>(state, operation, cost));

                // Move one step up the reverse path
                currentReverseNode = reverseParentNode;
            }

            // Return the last forward search node found
            return currentForwardNode;
        }
    }
}


/*
 * Copyright The Sett Ltd, 2005 to 2014.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.thesett.aima.logic.fol.prolog;

import java.util.HashMap;
import java.util.Map;

import com.thesett.aima.logic.fol.BaseTermTransformer;
import com.thesett.aima.logic.fol.Variable;
import com.thesett.aima.logic.fol.VariableTransformer;

/**
 * StackVariableTransform implements a compilation transformation, that replaces all variables in a term with stack
 * variables, assigned to stack slots sequentially from a specified offset, with a variable binding context.
 *
 *

CRC Card

 *
 Responsibilities  Collaborations
 *
 Replace variables with stack assigned variables.
 *

 *
 * @author Rupert Smith
 */
public class StackVariableTransform extends BaseTermTransformer implements VariableTransformer
{
    /** Used to build up a mapping from normal variables to stack variables. */
    protected Map<Variable, StackVariable> varMapping = new HashMap<Variable, StackVariable>();

    /** This is used to number the stack positions as variables are encountered. */
    protected int offset;

    /** Used to build up the result of the current compilation in. */
    protected VariableBindingContextSupplier context;

    /**
     * Creates a stack variable transformation that assigns variables to stack slots numbered from the specified offset
     * within the specified binding context.
     *
     * @param offset  The start offset to number stack slots form.
     * @param context The variable binding context that supplies the stack frame.
     */
    public StackVariableTransform(int offset, VariableBindingContextSupplier context)
    {
        this.offset = offset;
        this.context = context;
    }

    /**
     * {@inheritDoc}
     *
     *
Replaces all of the free variables in the clause with stack variables.
     */
    public Variable transform(Variable variable)
    {
        StackVariable stackVar = varMapping.get(variable);

        // Check if a stack variable for the variable has not been created yet, and if so create a new stack variable,
        // setting the clause that it is in as its binding context supplier.
        if (stackVar == null)
        {
            stackVar = new StackVariable(variable.getName(), null, variable.isAnonymous(), offset++, context);
            varMapping.put(variable, stackVar);
        }

        return stackVar;
    }
}


/*
 * Copyright The Sett Ltd, 2005 to 2014.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.thesett.common.util;

import java.io.Serializable;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * LazyPagingList is a list implementation that fetches its elements in blocks as needed. It is intended to be used for
 * displaying lists of results in user interfaces where the results list is split into pages (or is displayed in a
 * window that can only display so many elements at once). Implementations must provide the {@link #getBlock} method
 * that gets blocks of elements for the list. This list caching works best when accessed sequentially, rather than
 * randomly.
 *
 *

CRC Card

 *
ResponsibilitiesCollaborations
 *

 *
 * @author Rupert Smith
 */
public abstract class LazyPagingList<T> extends AbstractList<T> implements Serializable
{
    /** Used for logging. */
    /* private static final Logger log = Logger.getLogger(LazyPagingList.class.getName()); */

    /** Holds the final size of the list. */
    private int size;

    /** Holds the caching block size for the list. */
    private int blockSize;

    /** Holds the cache of blocks. */
    Map<Integer, List<T>> blockMap = new HashMap<Integer, List<T>>();

    /**
     * Sublcasses must call this constructor with the lists size.
     *
     * @param size      The size of the list.
     * @param blockSize The size of data block chunk to use when fetching data.
     */
    public LazyPagingList(int size, int blockSize)
    {
        /*log.fine("public LazyPagingList(int size, int blockSize): called");*/
        /*log.fine("size = " + size);*/
        /*log.fine("blockSize = " + blockSize);*/

        // Keep the sizes.
        this.size = size;
        this.blockSize = blockSize;
    }

    /** No args constructor for serialization. */
    public LazyPagingList()
    {
    }

    /**
     * Fetches a block of elements from within the underlying list. If the last block of the underlying list is
     * requested and it does not completely fill the block that a partial list not containing the full number of
     * elements may be returned.
     *
     * @param  start  The start index to fetch from.
     * @param  number The number of elements to get.
     *
     * @return A list taken from the underlying list starting at, start, and containing up to, number, of elements.
     */
    public abstract List<T> getBlock(int start, int number);

    /**
     * Gets the size of the list.
     *
     * @return the size of the list.
     */
    public int size()
    {
        return size;
    }

    /**
     * Updates the size of the list.
     *
     * @param size The new size.
     */
    public void setSize(int size)
    {
        this.size = size;
    }

    /**
     * Gets the element from the list at the specified index. If the indexes block is not currently cached then a call
     * is made to the {@link #getBlock} method to fetch it.
     *
     * @param  index The offset into the list to retrieve.
     *
     * @return The element at the specified index.
     */
    public T get(int index)
    {
        /*log.fine("public T get(int index): called");*/
        /*log.fine("index = " + index);*/

        // Turn the absolute index into a block and offset.
        int block = index / blockSize;
        int offset = index % blockSize;

        /*log.fine("block = " + block);*/
        /*log.fine("offset = " + offset);*/

        // Check if the desired block is already cached.
        List<T> blockList = blockMap.get(block);

        // Fetch the block if it is not already cached and cache it.
        if (blockList == null)
        {
            blockList = cacheBlock(block);
        }

        // Get the element from the offset within the cached block.
        return blockList.get(offset);
    }

    /**
     * Fetches and caches the specified block.
     *
     * @param  block The block to cache.
     *
     * @return The contents of the cached block.
     */
    public List<T> cacheBlock(int block)
    {
        /*log.fine("public List<T> cacheBlock(int block): called");*/

        // Get the new block.
        List<T> blockList = getBlock(block * blockSize, blockSize);

        // Cache it.
        blockMap.put(block, blockList);
        /*log.fine("Cached block " + block + " with list of size " + blockList.size());*/

        return blockList;
    }

    /**
     * Renders as a string for debugging purposes.
     *
     * @return A string for debugging purposes.
     */
    public String toString()
    {
        String result = "size: " + size + ", blockSize: " + blockSize;

        // Render only the blocks that are currently filled in.
        List<Integer> blocks = new ArrayList<Integer>(blockMap.keySet());
        Collections.sort(blocks);

        for (int block : blocks)
        {
            List<T> list = blockMap.get(block);

            result += ", [from: " + (block * blockSize);
            result += ", to: " + ((block * blockSize) + list.size() - 1);
            result += ", " + list + "]";
        }

        return result;
    }
}


/*
 * Copyright The Sett Ltd, 2005 to 2014.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.thesett.common.properties;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * DefaultPropertyReader is a factory class that creates a property reader from a named resource. The name is used to
 * locate the properties in the same way as described in the {@link PropertyReaderBase} class comment.
 *
 *
DefaultPropertyReader will create only one property reader per resource name. If the same name is requested more
 * than once then a previous singleton instance will be returned.
 *
 *

CRC Card

 *
ResponsibilitiesCollaborations
 *
Create a property reader from a resource name  {@link PropertyReaderBase}
 *

 *
 * @author Rupert Smith
 * @todo   Merge the functionality of the com.thesett.common.properties.ContextualProperties class in the junitppmod
 *         project into this class and then delete that one. It provides more sophisticated property handling than this
 *         class that allows properties to be defined on a per environment/class/method level with default values. This
 *         provides look up on the classpath, by location named by system property and in current working directory.
 *         Combined together they provide a very powerful way of looking up properties in a prioritsed and hierarchical
 *         way that is easy to use.
 */
public class DefaultPropertyReader extends PropertyReaderBase
{
    /** Used for logging. */
    /* private static final Logger log = Logger.getLogger(DefaultPropertyReader.class.getName()); */

    /** Used to hold a map from property resource names to singleton property reader instances. */
    private static final Map propertyReaders = new HashMap();

    /** Used to hold the name of the property resource. */
    private final String resourceName;

    /**
     * Private constructor that builds a property reader for a named resource. This is private to ensure that only
     * singleton instances of property readers can be created for each named resource.
     *
     * @param resourceName The name of the property file resource.
     */
    private DefaultPropertyReader(String resourceName)
    {
        /*log.fine("private DefaultPropertyReader(String resourceName): called");*/
        /*log.fine("resourceName = " + resourceName);*/

        // Keep the name of the properties resource
        this.resourceName = resourceName;

        // Load the properties resource
        findProperties();
    }

    /**
     * Static factory method that locates an existing instance or creates a new property reader for a named resource.
     *
     * @param  resourceName The name of the property file resource.
     *
     * @return The properties found under that resource name.
     */
    public static synchronized Properties getProperties(String resourceName)
    {
        /*log.fine("public static synchronized Properties getProperties(String resourceName): called");*/
        /*log.fine("resourceName = " + resourceName);*/

        // Try to find an already created singleton property reader for the resource
        PropertyReaderBase propertyReader = (PropertyReaderBase) propertyReaders.get(resourceName);

        if (propertyReader != null)
        {
            /*log.fine("found property reader in the cache for resource: " + resourceName);*/

            return propertyReader.getProperties();
        }

        /*log.fine("did not find property reader in the cache for resource: " + resourceName);*/

        // There is not already a singleton for the named resource so create a new one
        propertyReader = new DefaultPropertyReader(resourceName);

        // Keep the newly created singleton for next time
        propertyReaders.put(resourceName, propertyReader);

        return propertyReader.getProperties();
    }

    /**
     * This should return the name of the resource, file or system property to use to locate the properties file to be
     * read.
     *
     * @return The name of the property file resource.
     */
    public String getPropertiesResourceName()
    {
        /*log.fine("public String getPropertiesResourceName(): called");*/
        /*log.fine("resourceName = " + resourceName);*/

        return resourceName;
    }
}


/*
 * Copyright The Sett Ltd, 2005 to 2014.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.thesett.common.throttle;

/**
 * BatchedThrottle is a {@link SleepThrottle} that uses batching to achieve much higher throttling rates than a sleep
 * throttle can. Sleep throttle has difficulties once the rate gets above a few hundred hertz, because the JVM cannot
 * generate timed pauses that are that short. BatchedThrottle gets around this by only inserting pauses once every so
 * many calls to the {@link Throttle#throttle()} method, and using a sleep throttle run at a lower rate. The rate for
 * the sleep throttle is chosen so that it remains under 100hz. The final throttling rate of this throttle is equal to
 * the batch size times the rate of the underlying sleep throttle.
 *
 *
The batching calculation involves taking the log to the base 100 of the desired rate and rounding this to an
 * integer. The batch size is always an exact power of 100 because of the rounding. The rate for an underlying sleep
 * throttle is then chosen appropriately.
 *
 *
In practice, the accuracy of a BacthedThrottle skews off but can sometimes even be reasonable up to ten thousand
 * hertz compared with 100 Hz for a {@link SleepThrottle}.
 *
 *

CRC Card

 *
ResponsibilitiesCollaborations
 *
Accept throttling rate in operations per second.
 *
Inject short pauses, occasionaly, to fill out processing cycles to a specified rate.
 *
Check against a throttle speed without waiting.
 *

 *
 * @author Rupert Smith
 * @todo   Should always round the log base 100 down to the nearest integer?
 */
public class BatchedThrottle extends BaseThrottle
{
    /** Holds the batch size. */
    int batchSize;

    /** The call count within the current batch. */
    long callCount;

    /** Holds a sleep throttle configured to run at the batched rate. */
    private final Throttle batchRateThrottle = new SleepThrottle();

    /**
     * Specifies the throttling rate in operations per second.
     *
     * @param hertz The throttling rate in cycles per second.
     */
    public void setRate(float hertz)
    {
        // Pass the rate unaltered down to the base implementation, for the check method.
        super.setRate(hertz);

        // Log base 10 over 2 is used here to get a feel for what power of 100 the total rate is.
        // As the total rate goes up the powers of 100 the batch size goes up by powers of 100 to keep the
        // throttle rate in the range 1 to 100.
        int x = (int) (Math.log10(hertz) / 2);
        batchSize = (int) Math.pow(100, x);

        float throttleRate = hertz / batchSize;

        // Reset the call count.
        callCount = 0;

        // Set the sleep throttle wrapped implementation at a rate within its abilities.
        batchRateThrottle.setRate(throttleRate);
    }

    /**
     * Throttle calls to this method to the rate specified by the {@link #setRate(float)} method.
     *
     * @throws InterruptedException If interrupted whilst performing a blocking wait on the throttle.
     */
    public void throttle() throws InterruptedException
    {
        if ((callCount++ % batchSize) == 0)
        {
            batchRateThrottle.throttle();
        }
    }
}


/*
 * Copyright The Sett Ltd, 2005 to 2014.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.thesett.common.io;

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.rmi.RemoteException;

/**
 * This is a client proxy to a distributed input stream. It extends the {@link java.io.InputStream} class and is
 * therefore an InputStream itself and can be used in any situation in which an InputStream may be used. This client is
 * serializable and built from a distributed input stream. It provides a convenient way to return an input stream
 * accross an RMI call. It also hides the RemoteExceptions that may result from using RMI and returns these as
 * IOExceptions instead.
 *
 *

CRC Card

 *
ResponsibilitiesCollaborations
 *
Provide proxy wrapper to distributed input stream
 *  {@link DistributedInputStream}
 *

 *
 * @author Rupert Smith
 */
public class ClientInputStream extends InputStream implements Serializable
{
    /** Used for logging. */
    //private static java.util.logging.Logger log = java.util.logging.Logger.getLogger(ClientInputStream.class.getName());

    /** The source end of the distributed input stream. */
    DistributedInputStream source;

    /**
     * Builds a client input stream proxy from a distributed input stream.
     *
     * @param src The distributes input stream to wrap as an InputStream.
     */
    public ClientInputStream(DistributedInputStream src)
    {
        super();
        source = src;
    }

    /**
     * Returns the number of bytes that can be read (or skipped over) from this input stream without blocking by the
     * next caller of a method for this input stream.
     *
     * @return The number of bytes that can be read from this input stream.
     *
     * @throws IOException If an I/O error occurs when accessing the stream or a remote exception occurs.
     */
    public int available() throws IOException
    {
        try
        {
            return source.available();
        }
        catch (RemoteException e)
        {
            throw new IOException("There was a Remote Exception.", e);
        }
    }

    /**
     * Closes this input stream and releases any system resources associated with the stream.
     *
     * @throws IOException If an I/O error occurs when accessing the stream or a remote exception occurs.
     */
    public void close() throws IOException
    {
        try
        {
            source.close();
        }
        catch (RemoteException e)
        {
            throw new IOException("There was a Remote Exception.", e);
        }
    }

    /**
     * Marks the current position in this input stream.
     *
     * @param readlimit The maximum limit of bytes that can be read before the mark position becomes invalid.
     */
    public void mark(int readlimit)
    {
        try
        {
            source.mark(readlimit);
        }
        catch (RemoteException e)
        {
            throw new IllegalStateException("There was a RemoteException.", e);
        }
    }

    /**
     * Tests if this input stream supports the mark and reset methods.
     *
     * @return True if this stream instance supports the mark and reset methods, false otherwise.
     */
    public boolean markSupported()
    {
        try
        {
            return source.markSupported();
        }
        catch (RemoteException e)
        {
            throw new IllegalStateException("There was a RemoteException.", e);
        }
    }

    /**
     * Reads the next byte of data from the input stream.
     *
     * @return The next byte of data, or -1 if the end of the stream is reached.
     *
     * @throws IOException If an I/O error occurs when accessing the stream or a remote exception occurs.
     */
    public int read() throws IOException
    {
        try
        {
            return source.read();
        }
        catch (RemoteException e)
        {
            throw new IOException("There was a Remote Exception.", e);
        }
    }

    /**
     * Reads some number of bytes from the input stream and stores them into the buffer array b.
     *
     * @param  b The buffer into which the data is read.
     *
     * @return The total number of bytes read into the buffer, or -1 is there is no more data because the end of the
     *         stream has been reached.
     *
     * @throws IOException If an I/O error occurs when accessing the stream or a remote exception occurs.
     */
    public int read(byte[] b) throws IOException
    {
        try
        {
            ByteBlock block = source.read(b);

            System.arraycopy(block.data, 0, b, 0, block.count);

            return block.count;
        }
        catch (RemoteException e)
        {
            throw new IOException("There was a Remote Exception.", e);
        }
    }

    /**
     * Reads up to len bytes of data from the input stream into an array of bytes.
     *
     * @param  b   The buffer into which the data is read.
     * @param  off The start offset in array b at which the data is written.
     * @param  len The maximum number of bytes to read.
     *
     * @return The total number of bytes read into the buffer, or -1 is there is no more data because the end of the
     *         stream has been reached.
     *
     * @throws IOException If an IOException occurs in the wrapped distributed input stream or a remote exception
     *                     occurs.
     */
    public int read(byte[] b, int off, int len) throws IOException
    {
        try
        {
            ByteBlock block = source.read(b, off, len);

            System.arraycopy(block.data, off, b, off, len);

            return block.count;
        }
        catch (RemoteException e)
        {
            throw new IOException("There was a Remote Exception.", e);
        }
    }

    /**
     * Repositions this stream to the position at the time the mark method was last called on this input stream.
     *
     * @throws IOException If a remote exception occurs.
     */
    public void reset() throws IOException
    {
        try
        {
            source.reset();
        }
        catch (RemoteException e)
        {
            throw new IOException("There was a Remote Exception.", e);
        }
    }

    /**
     * Skips over and discards n bytes of data from this input stream.
     *
     * @param  n The number of bytes to skip.
     *
     * @return The actual number of bytes skipped.
     *
     * @throws IOException If an IOException occurs in the wrapped distributed input stream or a remote exception
     *                     occurs.
     */
    public long skip(long n) throws IOException
    {
        try
        {
            return source.skip(n);
        }
        catch (RemoteException e)
        {
            throw new IOException("There was a Remote Exception.", e);
        }
    }
}


/*
 * Copyright The Sett Ltd, 2005 to 2014.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.thesett.aima.logic.fol.wam.builtins;

import java.util.ArrayList;
import java.util.List;

import com.thesett.aima.logic.fol.Functor;
import com.thesett.aima.logic.fol.FunctorName;
import com.thesett.aima.logic.fol.Term;
import com.thesett.aima.logic.fol.wam.compiler.DefaultBuiltIn;
import static com.thesett.aima.logic.fol.wam.compiler.SymbolTableKeys.SYMKEY_PERM_VARS_REMAINING;
import com.thesett.aima.logic.fol.wam.compiler.WAMInstruction;
import com.thesett.aima.logic.fol.wam.compiler.WAMLabel;
import com.thesett.common.util.SizeableLinkedList;

/**
 * Disjunction implements the Prolog disjunction operator ';' that sets up multiple choice points potentially leading to
 * multiple solutions.
 *
 *

CRC Card

 *
 Responsibilities  Collaborations
 *
 Implement the disjunction operator.
 *

 *
 * @author Rupert Smith
 */
public class Disjunction extends BaseBuiltIn
{
    /**
     * Creates a cut built-in to implement the specified functor.
     *
     * @param functor        The functor to implement as a built-in.
     * @param defaultBuiltIn The default built in, for standard compilation and interners and symbol tables.
     */
    public Disjunction(Functor functor, DefaultBuiltIn defaultBuiltIn)
    {
        super(functor, defaultBuiltIn);
    }

    /** {@inheritDoc} */
    public SizeableLinkedList<WAMInstruction> compileBodyArguments(Functor functor, boolean isFirstBody,
        FunctorName clauseName, int bodyNumber)
    {
        SizeableLinkedList<WAMInstruction> result = new SizeableLinkedList<WAMInstruction>();
        SizeableLinkedList<WAMInstruction> instructions;

        // Invent some unique names for choice points within a clause.
        clauseName = new FunctorName(clauseName.getName() + "_" + bodyNumber, 0);

        FunctorName choicePointRootName = new FunctorName(clauseName.getName() + "_ilc", 0);
        FunctorName continuationPointName = new FunctorName(clauseName.getName() + "_cnt", 0);

        // Labels the continuation point to jump to, when a choice point succeeds.
        WAMLabel continueLabel = new WAMLabel(continuationPointName, 0);

        // Do a loop over the children of this disjunction, and any child disjunctions encountered. This could be a
        // search? or just recursive exploration. I think it will need to be a DFS.
        List<Term> expressions = new ArrayList<Term>();
        gatherDisjunctions((Disjunction) functor, expressions);

        for (int i = 0; i < expressions.size(); i++)
        {
            Functor expression = (Functor) expressions.get(i);

            boolean isFirst = i == 0;
            boolean isLast = i == (expressions.size() - 1);

            // Labels the entry point to each choice point.
            WAMLabel entryLabel = new WAMLabel(choicePointRootName, i);

            // Label for the entry point to the next choice point, to backtrack to.
            WAMLabel retryLabel = new WAMLabel(choicePointRootName, i + 1);

            if (isFirst && !isLast)
            {
                // try me else.
                result.add(new WAMInstruction(entryLabel, WAMInstruction.WAMInstructionSet.TryMeElse, retryLabel));
            }
            else if (!isFirst && !isLast)
            {
                // retry me else.
                result.add(new WAMInstruction(entryLabel, WAMInstruction.WAMInstructionSet.RetryMeElse, retryLabel));
            }
            else if (isLast)
            {
                // trust me.
                result.add(new WAMInstruction(entryLabel, WAMInstruction.WAMInstructionSet.TrustMe));
            }

            Integer permVarsRemaining =
                (Integer) defaultBuiltIn.getSymbolTable().get(expression.getSymbolKey(), SYMKEY_PERM_VARS_REMAINING);

            // Select a non-default built-in implementation to compile the functor with, if it is a built-in.
            BuiltIn builtIn;

            if (expression instanceof BuiltIn)
            {
                builtIn = (BuiltIn) expression;
            }
            else
            {
                builtIn = defaultBuiltIn;
            }

            // The 'isFirstBody' parameter is only set to true, when this is the first functor of a rule.
            instructions = builtIn.compileBodyArguments(expression, false, clauseName, i);
            result.addAll(instructions);

            // Call the body. The number of permanent variables remaining is specified for environment trimming.
            instructions = builtIn.compileBodyCall(expression, false, false, false, 0 /*permVarsRemaining*/);
            result.addAll(instructions);

            // Proceed if this disjunctive branch completes successfully. This does not need to be done for the last
            // branch, as the continuation point will come immediately after.
            if (!isLast)
            {
                result.add(new WAMInstruction(null, WAMInstruction.WAMInstructionSet.Continue, continueLabel));
            }
        }

        result.add(new WAMInstruction(continueLabel, WAMInstruction.WAMInstructionSet.NoOp));

        return result;
    }

    /** {@inheritDoc} */
    public SizeableLinkedList<WAMInstruction> compileBodyCall(Functor expression, boolean isFirstBody,
        boolean isLastBody, boolean chainRule, int permVarsRemaining)
    {
        return new SizeableLinkedList<WAMInstruction>();
    }

    /**
     * Creates a string representation of this functor, mostly used for debugging purposes.
     *
     * @return A string representation of this functor.
     */
    public String toString()
    {
        return "Disjunction: [ arguments = " + toStringArguments() + " ]";
    }

    /**
     * Gathers the functors to compile as a sequence of choice points. These exist as the arguments to disjunctions
     * recursively below the supplied disjunction. They are flattened into a list, by performing a left-to-right depth
     * first traversal over the disjunctions, and adding their arguments into a list.
     *
     * @param disjunction The disjunction to explore the arguments of.
     * @param expressions The flattened list of disjunctive terms.
     */
    private void gatherDisjunctions(Disjunction disjunction, List<Term> expressions)
    {
        // Left argument.
        gatherDisjunctionsExploreArgument(disjunction.getArguments()[0], expressions);

        // Right argument.
        gatherDisjunctionsExploreArgument(disjunction.getArguments()[1], expressions);
    }

    /**
     * Explores one argument of a disjunction as part of the {@link #gatherDisjunctions(Disjunction, List)} function.
     *
     * @param term        The argument to explore.
     * @param expressions The flattened list of disjunctive terms.
     */
    private void gatherDisjunctionsExploreArgument(Term term, List<Term> expressions)
    {
        if (term instanceof Disjunction)
        {
            gatherDisjunctions((Disjunction) term, expressions);
        }
        else
        {
            expressions.add(term);
        }
    }
}


/*
 * Copyright The Sett Ltd, 2005 to 2014.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.thesett.aima.logic.fol.prolog.builtins;

import com.thesett.aima.logic.fol.Functor;
import com.thesett.aima.logic.fol.NumericType;

/**
 * BinaryArithmeticComparison provides a base class for implementing two-place arithmetic comparisons on numeric
 * arguments. The arguments are evaluated in the same way as the argument to the 'is' operator is evaluated, that is,
 * any arithmetic operators are evaluated and the result is checked to ensure that it is numeric and fully instantiated.
 * After this, the {@link #evaluate} method is invoked to determine the outcome of the arithmetic comparison.
 *
 *

CRC Card

 *
 Responsibilities  Collaborations
 *
 Ensure that both arguments evaluate to fully instantiated numbers.  {@link NumericType}.
 *
 Evaluate the arithmetic comparison.
 *

 *
 * @author Rupert Smith
 */
public abstract class BinaryArithmeticComparison extends BaseBuiltIn
{
    /**
     * Creates a binary arithmetic built-in to implement the specified functor.
     *
     * @param functor The functor to implement as a built-in.
     */
    protected BinaryArithmeticComparison(Functor functor)
    {
        super(functor);
    }

    /** {@inheritDoc} */
    public boolean proofStep(ResolutionState state)
    {
        Functor isOp = state.getGoalStack().poll().getFunctor();

        // Evaluate both sides of the comparison, checking that they are fully instantiated numbers.
        NumericType n1 = BuiltInUtils.evaluateAsNumeric(isOp.getArgument(0));
        NumericType n2 = BuiltInUtils.evaluateAsNumeric(isOp.getArgument(1));

        // Evaluate the comparison operator.
        return evaluate(n1, n2);
    }

    /**
     * Evaluates the arithmetic comparison on its two numeric arguments.
     *
     * @param  firstNumber  The first argument.
     * @param  secondNumber The second argument.
     *
     * @return The result of performing the arithmetic comparison on its arguments.
     */
    protected abstract boolean evaluate(NumericType firstNumber, NumericType secondNumber);
}


/*
 * Copyright The Sett Ltd, 2005 to 2014.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.thesett.aima.logic.fol.wam.printer;

import com.thesett.aima.logic.fol.Clause;
import com.thesett.aima.logic.fol.VariableAndFunctorInterner;
import com.thesett.common.util.doublemaps.SymbolTable;

/**
 * Pretty printer for compiled queries.
 *
 *

CRC Card

 *
 Responsibilities  Collaborations
 *
 Pretty print compiled queries with internal information about the compilation.
 *

 *
 * @author Rupert Smith
 */
public class WAMCompiledQueryPrintingVisitor extends WAMCompiledTermsPrintingVisitor
{
    /**
     * Creates a pretty printing visitor for clauses being compiled in WAM.
     *
     * @param interner    The symbol name table.
     * @param symbolTable The symbol table for the compilation.
     * @param result      A string buffer to place the results in.
     */
    public WAMCompiledQueryPrintingVisitor(VariableAndFunctorInterner interner,
        SymbolTable<Integer, String, Object> symbolTable, StringBuffer result)
    {
        super(interner, symbolTable, result);
    }

    /** {@inheritDoc} */
    public void visit(Clause clause)
    {
        if (traverser.isEnteringContext())
        {
            initializePrinters();
        }
        else if (traverser.isLeavingContext())
        {
            printTable();
        }

        super.visit(clause);
    }
}


/*
 * Copyright The Sett Ltd, 2005 to 2014.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.thesett.common.util.priority;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import com.thesett.common.error.NotImplementedException;
import com.thesett.common.util.Function;

/**
 * BucketedPriorityMap is a {@link PriorityMap} that is implemented on top of java.util.HashMap. For each integer
 * priority level there is a hash map that contains the keys for a particular level.
 *
 *

CRC Card

 *
ResponsibilitiesCollaborations
 *

 *

 *
 * @author Rupert Smith
 */
public class BucketedPriorityMap<K, V> implements PriorityMap<K, V>
{
    /** Holds the priority mapping function to extract priority values from data elements. */
    Function<K, Integer> p;

    /** Holds that array of maps, one for each priority level. */
    Map<K, V>[] maps;

    /** The lowest priority value this queue accepts. */
    private final int lowest;

    /** The highest priority value this queue accepts. */
    private final int highest;

    /** The number of linked lists maintained by this nqueue. */
    private final int n;

    /**
     * Creates a bucketed priority map with the specified priority function over keys. The lowest and highest priority
     * levels generated by the priority function must be accurately specified too.
     *
     * @param lowest   The lowest priority level generated by the priority function.
     * @param highest  The highest priority level generated by the priority function.
     * @param priority The priority function over <K> that maps onto the range lowest ... highest.
     */
    public BucketedPriorityMap(int lowest, int highest, Function<K, Integer> priority)
    {
        // Sanity check the arguments.
        if (highest < lowest)
        {
            throw new IllegalArgumentException("The highest argument cannot be smaller than the lowest one.");
        }

        this.p = priority;
        this.lowest = lowest;
        this.highest = highest;
        n = highest - lowest + 1;

        // Create the buckets.
        maps = new Map[n];

        for (int i = 0; i < n; i++)
        {
            maps[i] = new HashMap<K, V>();
        }
    }

    /**
     * Returns the priority function associated with this prioty map, or <tt>null</tt> if it does not impose a priority
     * ordering.
     *
     * @return The priority function associated with this priority map, or <tt>null</tt> if it does not import a
     *         priority ordering.
     */
    public Function<K, Integer> priority()
    {
        return p;
    }

    /**
     * Returns the first (lowest) key currently in this priority map.
     *
     * @return The first (lowest) key currently in this priority map, or <tt>null</tt> if there is no first key.
     */
    public K pollKey()
    {
        // Scan through the buckets until a non empty one is found.
        int i = 0;

        for (; i < n; i++)
        {
            if (!maps[i].isEmpty())
            {
                break;
            }

            // If all maps are empty then the whole data structure is emtpy.
            if (i == (n - 1))
            {
                return null;
            }
        }

        return maps[i].keySet().iterator().next();
    }

    /**
     * Returns the value of the first (lowest) key currently in this priority map.
     *
     * @return The value of the first (lowest) key currently in this priority map.
     *
     * @throws java.util.NoSuchElementException If there are no keys in the map. This is thrown to distinguish from the
     *                                          case where the first key has a null value.
     */
    public V pollValue()
    {
        K lowestKey = pollKey();

        if (lowestKey == null)
        {
            return null;
        }
        else
        {
            return maps[p.apply(lowestKey)].get(lowestKey);
        }
    }

    /**
     * Returns the number of key-value mappings in this map. If the map contains more than <tt>Integer.MAX_VALUE</tt>
     * elements, returns <tt>Integer.MAX_VALUE</tt>.
     *
     * @return the number of key-value mappings in this map.
     */
    public int size()
    {
        throw new NotImplementedException();
    }

    /**
     * Returns <tt>true</tt> if this map contains no key-value mappings.
     *
     * @return <tt>true</tt> if this map contains no key-value mappings.
     */
    public boolean isEmpty()
    {
        throw new NotImplementedException();
    }

    /**
     * Returns <tt>true</tt> if this map maps one or more keys to the specified value. More formally, returns <tt>
     * true</tt> if and only if this map contains at least one mapping to a value <tt>v</tt> such that <tt>(value==null
     * ? v==null : value.equals(v))</tt>. This operation will probably require time linear in the map size for most
     * implementations of the <tt>Map</tt> interface.
     *
     * @param  value value whose presence in this map is to be tested.
     *
     * @return <tt>true</tt> if this map maps one or more keys to the specified value.
     *
     * @throws ClassCastException   if the value is of an inappropriate type for this map (optional).
     * @throws NullPointerException if the value is <tt>null</tt> and this map does not permit <tt>null</tt> values
     *                              (optional).
     */
    public boolean containsValue(Object value)
    {
        throw new NotImplementedException();
    }

    /**
     * Returns <tt>true</tt> if this map contains a mapping for the specified key. More formally, returns <tt>true</tt>
     * if and only if this map contains a mapping for a key <tt>k</tt> such that <tt>(key==null ? k==null :
     * key.equals(k))</tt>. (There can be at most one such mapping.)
     *
     * @param  key key whose presence in this map is to be tested.
     *
     * @return <tt>true</tt> if this map contains a mapping for the specified key.
     *
     * @throws ClassCastException   if the key is of an inappropriate type for this map (optional).
     * @throws NullPointerException if the key is <tt>null</tt> and this map does not permit <tt>null</tt> keys
     *                              (optional).
     */
    public boolean containsKey(Object key)
    {
        throw new NotImplementedException();
    }

    /**
     * Returns the value to which this map maps the specified key. Returns <tt>null</tt> if the map contains no mapping
     * for this key. A return value of <tt>null</tt> does not necessarily indicate that the map contains no
     * mapping for the key; it's also possible that the map explicitly maps the key to <tt>null</tt>. The <tt>
     * containsKey</tt> operation may be used to distinguish these two cases.
     *
     *

     *
More formally, if this map contains a mapping from a key <tt>k</tt> to a value <tt>v</tt> such that <tt>
     * (key==null ? k==null : key.equals(k))</tt>, then this method returns <tt>v</tt>; otherwise it returns <tt>
     * null</tt>. (There can be at most one such mapping.)
     *
     * @param  key key whose associated value is to be returned.
     *
     * @return the value to which this map maps the specified key, or <tt>null</tt> if the map contains no mapping for
     *         this key.
     *
     * @throws ClassCastException   if the key is of an inappropriate type for this map (optional).
     * @throws NullPointerException if the key is <tt>null</tt> and this map does not permit <tt>null</tt> keys
     *                              (optional).
     *
     * @see    #containsKey(Object)
     */
    public V get(Object key)
    {
        throw new NotImplementedException();
    }

    /**
     * Associates the specified value with the specified key in this map (optional operation). If the map previously
     * contained a mapping for this key, the old value is replaced by the specified value. (A map <tt>m</tt> is said to
     * contain a mapping for a key <tt>k</tt> if and only if {@link #containsKey(Object) m.containsKey(k)} would return
     * <tt>true</tt>.))
     *
     * @param  key   key with which the specified value is to be associated.
     * @param  value value to be associated with the specified key.
     *
     * @return previous value associated with specified key, or <tt>null</tt> if there was no mapping for key. A <tt>
     *         null</tt> return can also indicate that the map previously associated <tt>null</tt> with the specified
     *         key, if the implementation supports <tt>null</tt> values.
     *
     * @throws UnsupportedOperationException if the <tt>put</tt> operation is not supported by this map.
     * @throws ClassCastException            if the class of the specified key or value prevents it from being stored in
     *                                       this map.
     * @throws IllegalArgumentException      if some aspect of this key or value prevents it from being stored in this
     *                                       map.
     * @throws NullPointerException          if this map does not permit <tt>null</tt> keys or values, and the specified
     *                                       key or value is <tt>null</tt>.
     */
    public V put(K key, V value)
    {
        throw new NotImplementedException();
    }

    /**
     * Removes the mapping for this key from this map if it is present (optional operation). More formally, if this map
     * contains a mapping from key <tt>k</tt> to value <tt>v</tt> such that (key==null ? k==null :
     * key.equals(k)), that mapping is removed. (The map can contain at most one such mapping.)
     *
     *

     *
Returns the value to which the map previously associated the key, or <tt>null</tt> if the map contained no
     * mapping for this key. (A <tt>null</tt> return can also indicate that the map previously associated <tt>null</tt>
     * with the specified key if the implementation supports <tt>null</tt> values.) The map will not contain a mapping
     * for the specified key once the call returns.
     *
     * @param  key key whose mapping is to be removed from the map.
     *
     * @return previous value associated with specified key, or <tt>null</tt> if there was no mapping for key.
     *
     * @throws ClassCastException            if the key is of an inappropriate type for this map (optional).
     * @throws NullPointerException          if the key is <tt>null</tt> and this map does not permit <tt>null</tt> keys
     *                                       (optional).
     * @throws UnsupportedOperationException if the <tt>remove</tt> method is not supported by this map.
     */
    public V remove(Object key)
    {
        throw new NotImplementedException();
    }

    /**
     * Removes all mappings from this map (optional operation).
     *
     * @throws UnsupportedOperationException clear is not supported by this map.
     */
    public void clear()
    {
        throw new NotImplementedException();
    }

    /**
     * Copies all of the mappings from the specified map to this map (optional operation). The effect of this call is
     * equivalent to that of calling {@link #put(Object,Object) put(k, v)} on this map once for each mapping from key
     * <tt>k</tt> to value <tt>v</tt> in the specified map. The behavior of this operation is unspecified if the
     * specified map is modified while the operation is in progress.
     *
     * @param  t Mappings to be stored in this map.
     *
     * @throws UnsupportedOperationException if the <tt>putAll</tt> method is not supported by this map.
     * @throws ClassCastException            if the class of a key or value in the specified map prevents it from being
     *                                       stored in this map.
     * @throws IllegalArgumentException      some aspect of a key or value in the specified map prevents it from being
     *                                       stored in this map.
     * @throws NullPointerException          if the specified map is <tt>null</tt>, or if this map does not permit <tt>
     *                                       null</tt> keys or values, and the specified map contains <tt>null</tt> keys
     *                                       or values.
     */
    public void putAll(Map<? extends K, ? extends V> t)
    {
        throw new NotImplementedException();
    }

    /**
     * Returns a set view of the keys contained in this map. The set is backed by the map, so changes to the map are
     * reflected in the set, and vice-versa. If the map is modified while an iteration over the set is in progress
     * (except through the iterator's own <tt>remove</tt> operation), the results of the iteration are undefined. The
     * set supports element removal, which removes the corresponding mapping from the map, via the <tt>
     * Iterator.remove</tt>, <tt>Set.remove</tt>, <tt>removeAll</tt> <tt>retainAll</tt>, and <tt>clear</tt> operations.
     * It does not support the add or <tt>addAll</tt> operations.
     *
     * @return a set view of the keys contained in this map.
     */
    public Set<K> keySet()
    {
        throw new NotImplementedException();
    }

    /**
     * Returns a collection view of the values contained in this map. The collection is backed by the map, so changes to
     * the map are reflected in the collection, and vice-versa. If the map is modified while an iteration over the
     * collection is in progress (except through the iterator's own <tt>remove</tt> operation), the results of the
     * iteration are undefined. The collection supports element removal, which removes the corresponding mapping from
     * the map, via the <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt> and
     * <tt>clear</tt> operations. It does not support the add or <tt>addAll</tt> operations.
     *
     * @return a collection view of the values contained in this map.
     */
    public Collection<V> values()
    {
        throw new NotImplementedException();
    }

    /**
     * Returns a set view of the mappings contained in this map. Each element in the returned set is a
     * {@link java.util.Map.Entry}. The set is backed by the map, so changes to the map are reflected in the set, and
     * vice-versa. If the map is modified while an iteration over the set is in progress (except through the iterator's
     * own <tt>remove</tt> operation, or through the <tt>setValue</tt> operation on a map entry returned by the
     * iterator) the results of the iteration are undefined. The set supports element removal, which removes the
     * corresponding mapping from the map, via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>, <tt>removeAll</tt>,
     * <tt>retainAll</tt> and <tt>clear</tt> operations. It does not support the <tt>add</tt> or <tt>addAll</tt>
     * operations.
     *
     * @return a set view of the mappings contained in this map.
     */
    public Set<Entry<K, V>> entrySet()
    {
        throw new NotImplementedException();
    }
}


/*
 * Copyright The Sett Ltd, 2005 to 2014.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.thesett.common.util;

/**
 * ByteBufferUtils provides some helper methods for encoding and decoding values in a byte array.
 *
 *

CRC Card

 *
ResponsibilitiesCollaborations
 *
Read/Write int in byte array.
 *
Read/Write 24-bit int in byte array.
 *

 *
 * @author Rupert Smith
 * @todo   These encodings are all little endian. May need to write big endian versions too. A decision on standardizing
 *         the endian-ness of compiled programs needs to be taken. Little endian best for intel CPUs, big endian is the
 *         standard that Java uses.
 */
public class ByteBufferUtils
{
    /**
     * Extracts an int from an array of bytes.
     *
     * @param  buf    The array of bytes to extract the int from.
     * @param  offset The offset of the start of the int in the byte array.
     *
     * @return An integer extracted from the 4 bytes of data.
     */
    public static int getIntFromBytes(byte[] buf, int offset)
    {
        int result = 0;

        result += buf[offset++] & 0xFF;
        result += ((buf[offset++] & 0xFF) << 8);
        result += ((buf[offset++] & 0xFF) << 16);
        result += ((buf[offset]) << 24);

        return result;
    }

    /**
     * Outputs an int into a byte array.
     *
     * @param buf    The byte array to write to.
     * @param offset The offset within the byte array to output the int.
     * @param value  The int value to write into the array.
     */
    public static void writeIntToByteArray(byte[] buf, int offset, int value)
    {
        buf[offset++] = (byte) (value & 0x000000ff);
        buf[offset++] = (byte) ((value & 0x0000ff00) >> 8);
        buf[offset++] = (byte) ((value & 0x00ff0000) >> 16);
        buf[offset] = (byte) ((value & 0xff000000) >> 24);
    }

    /**
     * Outputs an int into a byte array, copying only the bottom 24 bits of the integer. The top, sign bit, is lost by
     * this operation, so this only works on positive ints below 2^24.
     *
     * @param buf    The byte array to write to.
     * @param offset The offset within the byte array to output the int.
     * @param value  The int value to write into the array.
     */
    public static void write24BitIntToByteArray(byte[] buf, int offset, int value)
    {
        buf[offset++] = (byte) (value & 0x000000ff);
        buf[offset++] = (byte) ((value & 0x0000ff00) >> 8);
        buf[offset] = (byte) ((value & 0x00ff0000) >> 16);
    }

    /**
     * Extracts an int from an array of bytes. Only three bytes are pulled together from the array to make a 24 bit
     * integer, albeit returned as a java 32 bit int.
     *
     * @param  buf    The array of bytes to extract the int from.
     * @param  offset The offset of the start of the int in the byte array.
     *
     * @return An integer extracted from the 4 bytes of data.
     */
    public static int get24BitIntFromBytes(byte[] buf, int offset)
    {
        int i = 0;

        offset++;
        i += buf[offset++] & 0xFF;
        i += ((buf[offset++] & 0xFF) << 8);
        i += ((buf[offset] & 0xFF) << 16);

        return i;
    }

    /**
     * Extracts a short from an array of bytes.
     *
     * @param  buf    The array of bytes to extract the short from.
     * @param  offset The offset of the start of the short in the byte array.
     *
     * @return A short extracted from the 2 bytes of data.
     */
    public static short getShortFromBytes(byte[] buf, int offset)
    {
        short result = 0;

        result += buf[offset++] & 0xFF;
        result += ((buf[offset]) << 8);

        return result;
    }

    /**
     * Outputs a short into a byte array.
     *
     * @param buf    The byte array to write to.
     * @param offset The offset within the byte array to output the short.
     * @param value  The short value to write into the array.
     */
    public static void writeShortToByteArray(byte[] buf, int offset, short value)
    {
        buf[offset++] = (byte) (value & 0x000000ff);
        buf[offset] = (byte) ((value & 0x0000ff00) >> 8);
    }
}


/*
 * Copyright The Sett Ltd, 2005 to 2014.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.thesett.aima.logic.fol.wam.builtins;

import com.thesett.aima.logic.fol.Functor;
import com.thesett.aima.logic.fol.FunctorName;
import com.thesett.aima.logic.fol.wam.compiler.DefaultBuiltIn;
import com.thesett.aima.logic.fol.wam.compiler.WAMInstruction;
import com.thesett.common.util.SizeableLinkedList;

/**
 * Implements the fail atom. This always fails without generating any choice points.
 *
 *

CRC Card

 *
 Responsibilities  Collaborations
 *
 Always fail, consuming the 'fail' goal.
 *

 *
 * @author Rupert Smith
 */
public class Fail extends BaseBuiltIn
{
    /**
     * Creates a fail built-in to implement the specified functor.
     *
     * @param functor        The functor to implement as a built-in.
     * @param defaultBuiltIn The default built in, for standard compilation and interners and symbol tables.
     */
    public Fail(Functor functor, DefaultBuiltIn defaultBuiltIn)
    {
        super(functor, defaultBuiltIn);
    }

    /** {@inheritDoc} */
    public SizeableLinkedList<WAMInstruction> compileBodyArguments(Functor expression, boolean isFirstBody,
        FunctorName clauseName, int bodyNumber)
    {
        return new SizeableLinkedList<WAMInstruction>();
    }

    /** {@inheritDoc} */
    public SizeableLinkedList<WAMInstruction> compileBodyCall(Functor expression, boolean isFirstBody,
        boolean isLastBody, boolean chainRule, int permVarsRemaining)
    {
        SizeableLinkedList<WAMInstruction> instructions = new SizeableLinkedList<WAMInstruction>();

        instructions.add(new WAMInstruction(WAMInstruction.WAMInstructionSet.Execute, new FunctorName("__fail__", 0)));

        return instructions;
    }

    /**
     * Creates a string representation of this functor, mostly used for debugging purposes.
     *
     * @return A string representation of this functor.
     */
    public String toString()
    {
        return "Fail";
    }
}


/*
 * Copyright The Sett Ltd, 2005 to 2014.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.thesett.aima.search.util.informed;

import java.util.Queue;

import com.thesett.aima.search.SearchNode;
import com.thesett.aima.search.Traversable;
import com.thesett.aima.search.impl.IterativeBoundAlgorithm;
import com.thesett.aima.search.spi.BoundProperty;
import com.thesett.common.util.StackQueue;

/**
 * Implements an iterative deepening A* search. This proceeds depth first but is bounded by iteratively increasing
 * values of f (f = heuristic + cost).
 *
 *
There are two version of this search. One increases the f-value in fixed increments rather than always taking the
 * next largest. Use the constructor that accepts an epsilon-value to use this version. The other will go to the next
 * largest f-value seen beyond the f-value bound on the previous iteration. If f only increases a few times accross a
 * search space this may be a usuable search. If it is different for every node then it will need to examine N^2 nodes
 * so it is too slow.
 *
 *

CRC Card

 *
 Responsibilities  Collaborations
 *
 Perform an optimal complete iterative deepening A* search.
 *
 Perform an epsilon admissable iterative deepening A* search.
 *

 *
 * @author Rupert Smith
 * @todo   Complete this comment about epsilon-admissable searches. If the heuristic is admissable then the IDA* search
 *         that uses the next f-value will be optimal and comlete. If an epsilon value is set then it is said to be
 *         epsilon-admissable which means the the cost of the solution will be???
 */
public class IDAStarSearch<O, T extends Traversable<O>> extends BaseHeuristicSearch<O, T> implements BoundProperty<O, T>
{
    /**
     * Creates a new IDAStarSearch object.
     *
     * @param heuristic The heuristic to use to compute heuristic values of search nodes with.
     * @param startF    The value of f to start the first iteration at.
     */
    public IDAStarSearch(Heuristic<O, T> heuristic, float startF)
    {
        super(heuristic);

        // Create an f increasing iterative algorithm by specializing the bounded algorithm with an
        // f-value extracting method.
        IterativeBoundAlgorithm<O, T> fIncreasingAlgorithm = new IterativeBoundAlgorithm<O, T>(startF);

        fIncreasingAlgorithm.setBoundPropertyExtractor(this);

        // Replace the search algorithm with the f-value increasing version.
        setQueueSearchAlgorithm(fIncreasingAlgorithm);
    }

    /**
     * Creates a new IDAStarSearch object.
     *
     * @param heuristic The heuristic to use to compute heuristic values of search nodes with.
     * @param startF    The value of f to start the first iteration at.
     * @param epsilon   The value to increase the f-limit by at each iteration.
     */
    public IDAStarSearch(Heuristic<O, T> heuristic, float startF, float epsilon)
    {
        super(heuristic);

        // Create an f increasing iterative algorithm by specializing the bounded algorithm with an
        // f-value extracting method.
        IterativeBoundAlgorithm<O, T> fIncreasingAlgorithm = new IterativeBoundAlgorithm<O, T>(startF, epsilon);

        fIncreasingAlgorithm.setBoundPropertyExtractor(this);

        // Replace the search algorithm with the f-value increasing version.
        setQueueSearchAlgorithm(fIncreasingAlgorithm);
    }

    /**
     * Provides an implementation of the {@link BoundProperty} interface to extract the cost as the bound property.
     *
     * @param  searchNode The search node to extract the bound property for.
     *
     * @return The f value of the supplied heuristic search node. The bound property to control the iterative deepening
     *         algorithm is f.
     */
    public float getBoundProperty(SearchNode<O, T> searchNode)
    {
        return ((HeuristicSearchNode<O, T>) searchNode).getF();
    }

    /**
     * Creates the correct type of queue for this search. This search uses a LIFO stack so that the child nodes most
     * recently added to the queue are examined first, ensuring that the search always goes deeper if it can.
     *
     * @return An empty LIFO stack.
     */
    public Queue<SearchNode<O, T>> createQueue()
    {
        return new StackQueue<SearchNode<O, T>>();
    }
}