package uk.ac.manchester.cs.jfact.helpers;
/* This file is part of the JFact DL reasoner
Copyright 2011-2013 by Ignazio Palmisano, Dmitry Tsarkov, University of Manchester
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA*/
import static uk.ac.manchester.cs.jfact.helpers.Helper.*;
import static uk.ac.manchester.cs.jfact.kernel.DagTag.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.semanticweb.owlapi.reasoner.ReasonerInternalException;
import uk.ac.manchester.cs.jfact.kernel.DLDag;
import uk.ac.manchester.cs.jfact.kernel.DagTag;
import uk.ac.manchester.cs.jfact.kernel.MergableLabel;
import uk.ac.manchester.cs.jfact.kernel.NamedEntry;
import uk.ac.manchester.cs.jfact.kernel.Role;
import conformance.Original;
import conformance.PortedFrom;
/**
* DL Vertex
*
* @author ignazio
*/
@PortedFrom(file = "dlVertex.h", name = "DLVertex")
public class DLVertex extends DLVertexTagDFS {
private static final long serialVersionUID = 11000L;
static class ChildSet implements Comparator<Integer>, Serializable {
private static final long serialVersionUID = 11000L;
protected final FastSet set = FastSetFactory.create();
private final SortedIntList original = new SortedIntList();
private int[] sorted = null;
protected DLDag sorter = null;
@Override
@PortedFrom(file = "dlVertex.h", name = "compare")
public int compare(Integer o1, Integer o2) {
return sorter.compare(o1, o2);
}
@Override
public boolean equals(Object arg0) {
if (arg0 == null) {
return false;
}
if (this == arg0) {
return true;
}
if (arg0 instanceof ChildSet) {
ChildSet arg = (ChildSet) arg0;
return set.equals(arg.set);
}
return false;
}
@Override
public int hashCode() {
return set.hashCode();
}
public void setSorter(DLDag d) {
sorter = d;
sorted = null;
}
public int[] sorted() {
if (sorted == null) {
sorted = new int[set.size()];
if (sorter == null) {
for (int i = 0; i < set.size(); i++) {
// if there is no sorting, use the original insertion
// order
sorted[i] = original.get(i);
}
} else {
List<Integer> l = new ArrayList<Integer>();
for (int i = 0; i < set.size(); ++i) {
l.add(set.get(i));
}
Collections.sort(l, this);
for (int i = 0; i < sorted.length; ++i) {
sorted[i] = l.get(i);
}
}
}
return sorted;
}
public boolean contains(int inverse) {
return set.contains(inverse);
}
public void clear() {
set.clear();
sorted = null;
}
public boolean add(int p) {
int size = set.size();
set.add(p);
if (set.size() > size) {
original.add(p);
sorted = null;
return true;
}
return false;
}
}
/** set of arguments (CEs, numbers for NR) */
@PortedFrom(file = "dlVertex.h", name = "Child")
private final ChildSet child = new ChildSet();
/** pointer to concept-like entry (for PConcept, etc) */
@PortedFrom(file = "dlVertex.h", name = "Concept")
private NamedEntry concept = null;
/** pointer to role (for E\A, NR) */
@PortedFrom(file = "dlVertex.h", name = "Role")
private final Role role;
/** projection role (used for projection op only) */
@PortedFrom(file = "dlVertex.h", name = "ProjRole")
private final Role projRole;
/** C if available */
@PortedFrom(file = "dlVertex.h", name = "C")
private int conceptIndex;
/** n if available */
@PortedFrom(file = "dlVertex.h", name = "n")
private final int n;
/** maximal depth, size and frequency of reference of the expression */
@PortedFrom(file = "dlVertex.h", name = "Sort")
private final MergableLabel sort = new MergableLabel();
/**
* get RW access to the label
*
* @return sort label
*/
@PortedFrom(file = "dlVertex.h", name = "getSort")
public MergableLabel getSort() {
return sort;
}
/**
* merge local label to label LABEL
*
* @param label
* label to merge
*/
@PortedFrom(file = "dlVertex.h", name = "merge")
public void merge(MergableLabel label) {
sort.merge(label);
}
/**
* c'tor for Top/CN/And (before adding any operands)
*
* @param op
* op
*/
public DLVertex(DagTag op) {
this(op, 0, null, bpINVALID, null);
}
/**
* c'tor for max n R_C; and for \A R{n}_C; Note order C, n, R.pointer
*
* @param op
* op
* @param m
* m
* @param R
* R
* @param c
* c
* @param ProjR
* ProjR
*/
public DLVertex(DagTag op, int m, Role R, int c, Role ProjR) {
super(op);
role = R;
projRole = ProjR;
conceptIndex = c;
n = m;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (this == obj) {
return true;
}
if (obj instanceof DLVertex) {
DLVertex v = (DLVertex) obj;
return op == v.op && compare(role, v.role)
&& compare(projRole, v.projRole)
&& conceptIndex == v.conceptIndex && n == v.n
&& child.equals(v.child);
}
return false;
}
@PortedFrom(file = "dlVertex.h", name = "compare")
private boolean compare(Object o1, Object o2) {
if (o1 == null) {
return o2 == null;
}
return o1.equals(o2);
}
@Override
public int hashCode() {
return (op == null ? 0 : op.hashCode())
+ (role == null ? 0 : role.hashCode())
+ (projRole == null ? 0 : projRole.hashCode()) + conceptIndex
+ n + (child == null ? 0 : child.hashCode());
}
/** @return C for concepts/quantifiers/NR verteces */
@PortedFrom(file = "dlVertex.h", name = "getC")
public int getConceptIndex() {
return conceptIndex;
}
/** @return N for the (max n R) vertex */
@PortedFrom(file = "dlVertex.h", name = "getNumberLE")
public int getNumberLE() {
return n;
}
/** @return N for the (min n R) vertex */
@PortedFrom(file = "dlVertex.h", name = "getNumberGE")
public int getNumberGE() {
return n + 1;
}
/** @return STATE for the (\all R{state}.C) vertex */
@PortedFrom(file = "dlVertex.h", name = "getState")
public int getState() {
return n;
}
/** @return pointer to the first concept name of the entry */
@PortedFrom(file = "dlVertex.h", name = "begin")
public int[] begin() {
return child.sorted();
}
/** @return pointer to Role for the Role-like verteces */
@PortedFrom(file = "dlVertex.h", name = "getRole")
public Role getRole() {
return role;
}
/** @return pointer to Projection Role for the Projection verteces */
@PortedFrom(file = "dlVertex.h", name = "getProjRole")
public Role getProjRole() {
return projRole;
}
/** @return TConcept for concept-like fields */
@PortedFrom(file = "dlVertex.h", name = "getConcept")
public NamedEntry getConcept() {
return concept;
}
/**
* set TConcept value to entry
*
* @param p
* p
*/
@PortedFrom(file = "dlVertex.h", name = "setConcept")
public void setConcept(NamedEntry p) {
concept = p;
}
/**
* set a concept (child) to Name-like vertex
*
* @param p
* p
*/
@PortedFrom(file = "dlVertex.h", name = "setChild")
public void setChild(int p) {
conceptIndex = p;
}
/**
* @param p
* p
* @return true if dtBad
*/
@PortedFrom(file = "dlVertex.h", name = "addChild")
public boolean addChild(int p) {
if (p == bpTOP) {
return false;
}
if (op == dtBad) {
return true;
}
if (p == bpBOTTOM) {
// clash:
child.clear();
op = dtBad;
return true;
}
if (child.contains(-p)) {
child.clear();
op = dtBad;
return true;
}
child.add(p);
return false;
}
/** @return andToDag */
@Original
public int getAndToDagValue() {
if (child.set.size() == 0) {
return bpTOP;
}
if (child.set.size() == 1) {
return child.set.get(0);
}
return bpINVALID;
}
/**
* @param dag
* dag
*/
@PortedFrom(file = "dlVertex.h", name = "sortEntry")
public void sortEntry(DLDag dag) {
if (op != dtAnd) {
return;
}
child.setSorter(dag);
}
/**
* @param extendedStats
* true if extended stats should be printed
* @return toString value
*/
public String toString(boolean extendedStats) {
StringBuilder o = new StringBuilder();
if (extendedStats) {
o.append("[d(");
o.append(stat[0]);
o.append('/');
o.append(stat[1]);
o.append("),s(");
o.append(stat[2]);
o.append('/');
o.append(stat[3]);
o.append("),b(");
o.append(stat[4]);
o.append('/');
o.append(stat[5]);
o.append("),g(");
o.append(stat[6]);
o.append('/');
o.append(stat[7]);
o.append("),f(");
o.append(stat[8]);
o.append('/');
o.append(stat[9]);
o.append(")] ");
}
o.append(toString());
return o.toString();
}
@Override
public String toString() {
switch (op) {
case dtAnd:
case dtCollection:
case dtSplitConcept:
break;
case dtTop:
case dtNN:
return op.getName();
case dtDataExpr:
return op.getName() + ' ' + concept;
case dtDataValue:
case dtDataType:
case dtPConcept:
case dtNConcept:
case dtPSingleton:
case dtNSingleton:
return op.getName()
+ String.format(Templates.DLVERTEXPrint2.getTemplate(),
concept.getName(),
op.isNNameTag() ? "=" : "[=", conceptIndex);
case dtLE:
return op.getName() + ' ' + n + ' ' + role.getName() + ' '
+ conceptIndex;
case dtForall:
return op.getName()
+ String.format(Templates.DLVERTEXPrint3.getTemplate(),
role.getName(), n, conceptIndex);
case dtIrr:
return op.getName() + ' ' + role.getName();
case dtProj:
return op.getName()
+ String.format(Templates.DLVERTEXPrint4.getTemplate(),
role.getName(), conceptIndex,
projRole.getName());
case dtChoose:
return op.getName() + ' ' + getConceptIndex();
default:
throw new ReasonerInternalException(String.format(
"Error printing vertex of type %s(%s)", op.getName(),
op));
}
StringBuilder o = new StringBuilder(op.getName());
for (int q : child.sorted()) {
o.append(' ').append(q);
}
return o.toString();
}
/** maximal depth, size and frequency of reference of the expression */
@PortedFrom(file = "dlVertex.h", name = "stat")
protected final int[] stat = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
/**
* add-up all stat values at once by explicit values
*
* @param d
* d
* @param s
* s
* @param b
* b
* @param g
* g
* @param pos
* pos
*/
@PortedFrom(file = "dlVertex.h", name = "updateStatValues")
public void updateStatValues(int d, int s, int b, int g, boolean pos) {
StatIndex.updateStatValues(d, s, b, g, pos, stat);
}
/**
* add-up all values at once by a given vertex
*
* @param v
* v
* @param posV
* posV
* @param pos
* pos
*/
@PortedFrom(file = "dlVertex.h", name = "updateStatValues")
public void updateStatValues(DLVertex v, boolean posV, boolean pos) {
StatIndex.updateStatValues(v, posV, pos, stat);
}
/**
* increment frequency value
*
* @param pos
* pos
*/
@PortedFrom(file = "dlVertex.h", name = "incFreqValue")
public void incFreqValue(boolean pos) {
StatIndex.incFreqValue(pos, stat);
}
// get methods
/**
* general access to a stat value by index
*
* @param i
* i
* @return stat at position i
*/
@PortedFrom(file = "dlVertex.h", name = "getStat")
public int getStat(int i) {
return stat[i];
}
/**
* general access to a stat value by index
*
* @param pos
* pos
* @return depth of queue pos
*/
@PortedFrom(file = "dlVertex.h", name = "getDepth")
public int getDepth(boolean pos) {
return StatIndex.getDepth(pos, stat);
}
/** usage statistic for pos- and neg occurences of a vertex */
@PortedFrom(file = "dlVertex.h", name = "posUsage")
protected final long posUsage = 0;
@PortedFrom(file = "dlVertex.h", name = "negUsage")
protected final long negUsage = 0;
/**
* get access to a usage wrt POS
*
* @param pos
* pos
* @return usage
*/
@PortedFrom(file = "dlVertex.h", name = "getUsage")
public long getUsage(boolean pos) {
return pos ? posUsage : negUsage;
}
}