/*
* Copyright (c) 2007 BUSINESS OBJECTS SOFTWARE LIMITED
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Business Objects nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* DirectedGraphDemo.java
* Created: Oct 15, 2007
* By: Joseph Wong
*/
package org.openquark.cal.samples.directedgraph;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.openquark.cal.runtime.CALExecutorException;
import org.openquark.cal.runtime.DebugSupport;
import org.openquark.cal.runtime.ExecutionContext;
import org.openquark.cal.runtime.lecc.StandaloneRuntime;
import org.openquark.util.Pair;
/**
* This class contains some demos of the functionality exposed via the {@link ImmutableDirectedGraph} class, which
* is a Java-generics friendly facade on top of the Java API provided by the standalone CAL library JAR built on
* top of the API module {@code Cal.Samples.DirectedGraphLibrary}.
* <p>
* Some examples are based on the work in the CAL module {@code Cal.Test.Utilities.DirectedGraph_Tests}.
* <p>
* For more information on the generation and use of standalone JARs, please refer to the document
* "Using Quark with Standalone JARs" included in the distribution.
*
* @see "Using Quark with Standalone JARs"
* @see ImmutableDirectedGraph
* @see org.openquark.cal.samples.directedgraph.DirectedGraphLibrary
*
* @author Andrew Casey
* @author Joseph Wong
*/
public final class DirectedGraphDemo {
/** An execution context for the various demos. */
private static final ExecutionContext executionContext = StandaloneRuntime.makeExecutionContext(DirectedGraphDemo.class);
/**
* The main method.
* @param args command line arguments.
*/
public static void main(final String[] args) throws CALExecutorException {
simpleGraphDemo();
factorsAndMultiplesDemo();
cycleTests();
}
/**
* Some simple demos of the directed graph class.
*/
private static void simpleGraphDemo() throws CALExecutorException {
// Construct a graph by starting with an empty graph and adding edges and vertices to it.
final ImmutableDirectedGraph<String> graph1 = ImmutableDirectedGraph
.<String>emptyGraph(executionContext)
.addEdge(Pair.make("one", "two"))
.addVertex("three");
// graph2 is graph1 with one more edge - this does not modify graph1
final ImmutableDirectedGraph<String> graph2 = graph1.addEdge(Pair.make("two", "three"));
// Let's look at graph2, both via its toString() implementation
System.out.println(graph2);
// ...and via the support to show the structure of a CalValue
System.out.println(DebugSupport.showInternal(graph2.getCalValue()));
// removeEdge does not modify graph1
System.out.println(graph1.removeEdge(Pair.make("one", "two")));
// ...as can be witnessed by displaying graph1
System.out.println(graph1);
}
/**
* A demo based on constructing graphs of integers where edges correspond to the divisibility relation.
*/
private static void factorsAndMultiplesDemo() throws CALExecutorException {
// Make a list of the Integers 1..100 as vertices
final List<Integer> ints = new ArrayList<Integer>();
for (int i = 1; i <= 100; i++) {
ints.add(Integer.valueOf(i));
}
// Construct a graph based on the vertices, and an edge a->b if b is a factor of a.
final ImmutableDirectedGraph<Integer> factorsGraph = ImmutableDirectedGraph
.makePredicateGraph(
ints,
new Predicate<Pair<Integer, Integer>>() {
public boolean apply(Pair<Integer, Integer> value) {
return value.fst().intValue() % value.snd().intValue() == 0;
}},
executionContext);
System.out.println(factorsGraph);
// Reversing the graph, we now have a graph with edges a->b for each pair (a,b) where b is a multiple of a.
final ImmutableDirectedGraph<Integer> multiplesGraph = factorsGraph.reverse();
System.out.println(multiplesGraph);
// We filter the multiplesGraph to contain only vertices that are perfect squares
final ImmutableDirectedGraph<Integer> squaresGraph = multiplesGraph.filter(new Predicate<Integer>() {
public boolean apply(Integer vertex) {
// a perfect square has an odd number of factors
try {
return factorsGraph.getNeighbours(vertex).size() % 2 == 1;
} catch (CALExecutorException e) {
throw new IllegalStateException(e);
}
}});
System.out.println(squaresGraph);
}
/**
* Tests graphs with and without cycles
*/
@SuppressWarnings("unchecked")
private static void cycleTests() throws CALExecutorException {
final ImmutableDirectedGraph<Integer> noCycles = ImmutableDirectedGraph
.makeGraph(
Collections.<Integer>emptyList(),
Arrays.asList(Pair.make(1, 2), Pair.make(2, 3), Pair.make(1, 3)),
executionContext);
final ImmutableDirectedGraph<Integer> lengthOneCycle = ImmutableDirectedGraph
.makeGraph(
Collections.<Integer>emptyList(),
Arrays.asList(Pair.make(1, 1)),
executionContext);
final ImmutableDirectedGraph<Integer> lengthTwoCycle = ImmutableDirectedGraph
.makeGraph(
Collections.<Integer>emptyList(),
Arrays.asList(Pair.make(1, 2), Pair.make(2, 1)),
executionContext);
System.out.println("noCycle.findCycle(): " + noCycles.findCycle());
System.out.println("oneCycle.findCycle(): " + lengthOneCycle.findCycle());
System.out.println("twoCycle.findCycle(): " + lengthTwoCycle.findCycle());
}
}