com.cyc.kb.client.KbPredicateImpl Maven / Gradle / Ivy
Show all versions of cyc-kb-client Show documentation
package com.cyc.kb.client;
/*
* #%L
* File: KbPredicateImpl.java
* Project: KB Client
* %%
* Copyright (C) 2013 - 2017 Cycorp, 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.
* #L%
*/
import com.cyc.base.cycobject.CycAssertion;
import com.cyc.base.cycobject.CycList;
import com.cyc.base.cycobject.CycObject;
import com.cyc.base.cycobject.DenotationalTerm;
import com.cyc.base.cycobject.Fort;
import com.cyc.base.cycobject.Guid;
import com.cyc.base.exception.CycApiException;
import com.cyc.base.exception.CycConnectionException;
import com.cyc.baseclient.CycObjectFactory;
import com.cyc.baseclient.cycobject.CycConstantImpl;
import com.cyc.kb.Context;
import com.cyc.kb.Fact;
import com.cyc.kb.KbCollection;
import com.cyc.kb.KbObject;
import com.cyc.kb.KbPredicate;
import com.cyc.kb.KbStatus;
import com.cyc.kb.Sentence;
import com.cyc.kb.client.config.KbConfiguration;
import com.cyc.kb.client.quant.QuantifiedInstanceRestrictedVariable;
import com.cyc.kb.exception.CreateException;
import com.cyc.kb.exception.InvalidNameException;
import com.cyc.kb.exception.KbException;
import com.cyc.kb.exception.KbObjectNotFoundException;
import com.cyc.kb.exception.KbRuntimeException;
import com.cyc.kb.exception.KbTypeConflictException;
import com.cyc.kb.exception.KbTypeException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A KBPredicate
object is a facade for a #$Predicate
* in Cyc KB.
*
* A predicate represents the property of a thing or the relationship between
* two or more things. Predicates are used to form #$CycLAtomicSentence and are
* in the 0th argument position. Well-formed (based on predicate arguments) and
* closed sentences can either be true or false.
*
* @param type of CycObject core
*
* @author Vijay Raj
* @version $Id: KbPredicateImpl.java 173082 2017-07-28 15:36:55Z nwinant $
*/
public class KbPredicateImpl extends RelationImpl implements KbPredicate {
public static final boolean VERBOSE_ADD_FACT_ERRORS = false;
private static final Logger LOG = LoggerFactory.getLogger(KbPredicateImpl.class.getName());
private static final DenotationalTerm TYPE_CORE =
new CycConstantImpl("Predicate", new Guid("bd5880d6-9c29-11b1-9dad-c379636f7270"));
static DenotationalTerm getClassTypeCore() {
return TYPE_CORE;
}
/**
* Not part of the KB API. This default constructor only has the effect of
* ensuring that there is access to a Cyc server.
*/
KbPredicateImpl() {
super();
}
public KbPredicateImpl (KbPredicate pred, Map kboData) {
super(pred, kboData);
}
/**
* Not part of the KB API. An implementation-dependent constructor.
*
* It is used when the result of query is a CycObject and is known to be or
* requested to be cast as an instance of KBPredicate.
*
* @param cycObject the CycObject wrapped by KBPredicate
. The
* constructor verifies that the CycObject is an instance of #$Predicate
*
* @throws KbTypeException if cycObject is not or could not be made an
* instance of #$Predicate
*/
KbPredicateImpl(DenotationalTerm cycObject) throws KbTypeException {
super(cycObject);
}
/**
* This not part of the public, supported KB API. finds or creates an instance of #$Predicate
* represented by predStr in the underlying KB
*
*
* @param predStr the string representing an instance of #$Predicate in the KB
*
* @throws CreateException if the #$Predicate represented by predStr is not
* found and could not be created
* @throws KbTypeException if the term represented by predStr is not an
* instance of #$Predicate and cannot be made into one.
*/
KbPredicateImpl(String predStr) throws KbTypeException, CreateException {
super(predStr);
}
/**
* This not part of the public, supported KB API. finds or creates; or finds an instance of
* #$Predicate represented by predStr in the underlying KB based on input ENUM
*
*
* @param predStr the string representing an instance of #$Predicate in the KB
* @param lookup the enum to specify LookupType: FIND or FIND_OR_CREATE
*
* @throws CreateException
* @throws KbTypeException
*
* @throws KbObjectNotFoundException if the #$Predicate represented by predStr
* is not found and could not be created
* @throws InvalidNameException if the string predStr does not conform to Cyc
* constant-naming conventions
*
* @throws KbTypeException if the term represented by predStr is not an
* instance of #$Predicate and lookup is set to find only
* {@link LookupType#FIND}
* @throws KbTypeConflictException if the term represented by predStr is not
* an instance of #$Predicate, and lookup is set to find or create; and if the
* term cannot be made an instance #$Predicate by asserting new knowledge.
*/
KbPredicateImpl(String predStr, LookupType lookup) throws KbTypeException, CreateException {
super(predStr, lookup);
}
/**
* Get the
* KBPredicate
with the name
* nameOrId
. Throws exceptions if there is no KB term by that
* name, or if it is not already an instance of #$Predicate.
*
* @param nameOrId the string representation or the HLID of the #$Predicate
*
* @return a new KBPredicate
*
* @throws KbTypeException
* @throws CreateException
*/
public static KbPredicateImpl get(String nameOrId) throws KbTypeException, CreateException {
return KbObjectImplFactory.get(nameOrId, KbPredicateImpl.class);
}
/**
* Get the
* KBPredicate
object that corresponds to
* cycObject
. Throws exceptions if the object isn't in the KB, or if
* it's not already an instance of
* #$Predicate
.
*
* @param cycObject the CycObject wrapped by KBPredicate. The method
* verifies that the CycObject is an instance of #$Predicate
*
* @return a new KBPredicate
*
* @throws CreateException
* @throws KbTypeException
*/
@Deprecated
public static KbPredicateImpl get(CycObject cycObject) throws KbTypeException, CreateException {
return KbObjectImplFactory.get(cycObject, KbPredicateImpl.class);
}
/**
* Find or create a
* KBPredicate
object named
* nameOrId
. If no object exists in the KB with the name
* nameOrId
, one will be created, and it will be asserted to be
* an instance of
* #$Predicate
. If there is already an object in the KB called
* nameOrId
, and it is already a
* #$Predicate
, it will be returned. If it is not already a
* #$Predicate
, but can be made into one by addition of
* assertions to the KB, such assertions will be made, and the object will be
* returned. If the object in the KB cannot be turned into a
* #$Predicate
by adding assertions (i.e. some existing
* assertion prevents it from being a
* #$Predicate
), a
* KBTypeConflictException
will be thrown.
*
* @param nameOrId the string representation or the HLID of the #$Predicate
*
* @return a new KBPredicate
*
* @throws KbTypeException
* @throws CreateException
*/
public static KbPredicateImpl findOrCreate(String nameOrId) throws CreateException, KbTypeException {
return KbObjectImplFactory.findOrCreate(nameOrId, KbPredicateImpl.class);
}
/**
* Find or create a KBPredicate object from
* cycObject
. If
* cycObject
is already a
* #$Predicate
, an appropriate
* KBPredicate
object will be returned. If
* object
is not already a
* #$Predicate
, but can be made into one by addition of
* assertions to the KB, such assertions will be made, and the relevant object
* will be returned. If
* cycObject
cannot be turned into a
* #$Predicate
by adding assertions (i.e. some existing
* assertion prevents it from being a
* #$Predicate
, a
* KBTypeConflictException
will be thrown.
*
* @param cycObject the CycObject wrapped by KBPredicate. The method
* verifies that the CycObject is an #$Predicate
*
* @return a new KBPredicate
*
* @throws KbTypeException
* @throws CreateException
*/
@Deprecated
public static KbPredicateImpl findOrCreate(CycObject cycObject) throws CreateException, KbTypeException {
return KbObjectImplFactory.findOrCreate(cycObject, KbPredicateImpl.class);
}
/**
* Find or create a
* KBPredicate
object named
* nameOrId
, and also make it an instance of
* constraintCol
in the default context specified by
* {@link KBAPIDefaultContext#forAssertion()}. If no object
* exists in the KB with the name
* nameOrId
, one will be created, and it will be asserted to be
* an instance of both
* #$Predicate
and
* constraintCol
. If there is already an object in the
* KB called
* nameOrId
, and it is already both a
* #$Predicate
and a
* constraintCol
, it will be returned. If it is not
* already both a
* #$Predicate
and a
* constraintCol
, but can be made so by addition of
* assertions to the KB, such assertions will be made, and the object will be
* returned. If the object in the KB cannot be turned into both a
* #$Predicate
and a
* constraintCol
by adding assertions, a
* KBTypeConflictException
will be thrown.
*
* @param nameOrId the string representation or the HLID of the #$Predicate
* @param constraintCol the collection that this #$Predicate will instantiate
*
* @return a new KBPredicate
*
* @throws KbTypeException
* @throws CreateException
*/
public static KbPredicateImpl findOrCreate(String nameOrId, KbCollection constraintCol) throws CreateException, KbTypeException {
return KbObjectImplFactory.findOrCreate(nameOrId, constraintCol, KbPredicateImpl.class);
}
/**
* Find or create a
* KBPredicate
object named
* nameOrId
, and also make it an instance of
* constraintCol
in the default context specified by
* {@link KBAPIDefaultContext#forAssertion()}. If no object
* exists in the KB with the name
* nameOrId
, one will be created, and it will be asserted to be
* an instance of both
* #$Predicate
and
* constraintCol
. If there is already an object in the
* KB called
* nameOrId
, and it is already both a
* #$Predicate
and a
* constraintCol
, it will be returned. If it is not
* already both a
* #$Predicate
and a
* constraintCol
, but can be made so by addition of
* assertions to the KB, such assertions will be made, and the object will be
* returned. If the object in the KB cannot be turned into both a
* #$Predicate
and a
* constraintCol
by adding assertions, a
* KBTypeConflictException
will be thrown.
*
* @param nameOrId the string representation or the HLID of the #$Predicate
* @param constraintColStr the string representation of the collection that
* this #$Predicate will instantiate
*
* @return a new KBPredicate
*
* @throws KbTypeException
* @throws CreateException
*/
public static KbPredicateImpl findOrCreate(String nameOrId, String constraintColStr) throws CreateException, KbTypeException {
return KbObjectImplFactory.findOrCreate(nameOrId, constraintColStr, KbPredicateImpl.class);
}
/**
* Find or create a
* KBPredicate
object named
* nameOrId
, and also make it an instance of
* constraintCol
in
* ctx
. If no object exists in the KB with the name
* nameOrId
, one will be created, and it will be asserted to be
* an instance of both
* #$Predicate
and
* constraintCol
. If there is already an object in the
* KB called
* nameOrId
, and it is already both a
* #$Predicate
and a
* constraintCol
, it will be returned. If it is not
* already both a
* #$Predicate
and a
* constraintCol
, but can be made so by addition of
* assertions to the KB, such assertions will be made, and the object will be
* returned. If the object in the KB cannot be turned into both a
* #$Predicate
and a
* constraintCol
by adding assertions, a
* KBTypeConflictException
will be thrown.
*
* @param nameOrId the string representation or the HLID of the #$Predicate
* @param constraintCol the collection that this #$Predicate will instantiate
* @param ctx the context in which the resulting object must be an instance of
* constraintCol
*
* @return a new KBPredicate
*
* @throws KbTypeException
* @throws CreateException
*/
public static KbPredicateImpl findOrCreate(String nameOrId, KbCollection constraintCol, ContextImpl ctx)
throws CreateException, KbTypeException {
return KbObjectImplFactory.findOrCreate(nameOrId, constraintCol, ctx, KbPredicateImpl.class);
}
/**
* Find or create a
* KBPredicate
object named
* nameOrId
, and also make it an instance of
* constraintCol
in
* ctx
. If no object exists in the KB with the name
* nameOrId
, one will be created, and it will be asserted to be
* an instance of both
* #$Predicate
and
* constraintCol
. If there is already an object in the
* KB called
* nameOrId
, and it is already both a
* #$Predicate
and a
* constraintCol
, it will be returned. If it is not
* already both a
* #$Predicate
and a
* constraintCol
, but can be made so by addition of
* assertions to the KB, such assertions will be made, and the object will be
* returned. If the object in the KB cannot be turned into both a
* #$Predicate
and a
* constraintCol
by adding assertions, a
* KBTypeConflictException
will be thrown.
*
* @param nameOrId the string representation or the HLID of the term
* @param constraintColStr the string representation of the collection that
* this #$Predicate will instantiate
* @param ctxStr the context in which the resulting object must be an instance of
* constraintCol
*
* @return a new KBPredicate
*
* @throws KbTypeException
* @throws CreateException
*/
public static KbPredicateImpl findOrCreate(String nameOrId, String constraintColStr, String ctxStr) throws CreateException, KbTypeException {
return KbObjectImplFactory.findOrCreate(nameOrId, constraintColStr, ctxStr, KbPredicateImpl.class);
}
/**
* Checks whether entity exists in KB and is an instance of #$Predicate. If
* false, {@link #getStatus(String)} may yield more information. This method
* is equivalent to
* getStatus(nameOrId).equals(KBStatus.EXISTS_AS_TYPE)
.
*
* @param nameOrId either the name or HL ID of an entity in the KB
* @return true
if entity exists in KB and is an instance of
* #$Predicate
*/
public static boolean existsAsType(String nameOrId) {
return getStatus(nameOrId).equals(KbStatus.EXISTS_AS_TYPE);
}
/**
* Checks whether entity exists in KB and is an instance of #$Predicate. If
* false, {@link #getStatus(CycObject)} may yield more information. This
* method is equivalent to
* getStatus(object).equals(KBStatus.EXISTS_AS_TYPE)
.
*
* @param cycObject the CycObject representation of a KB entity
* @return true
if entity exists in KB and is an instance of
* #$Predicate
*/
public static boolean existsAsType(CycObject cycObject) {
return getStatus(cycObject).equals(KbStatus.EXISTS_AS_TYPE);
}
/**
* Returns an KBStatus enum which describes whether nameOrId
* exists in the KB and is an instance of #$Predicate
.
*
* @param nameOrId either the name or HL ID of an entity in the KB
* @return an enum describing the existential status of the entity in the KB
*/
public static KbStatus getStatus(String nameOrId) {
return KbObjectImplFactory.getStatus(nameOrId, KbPredicateImpl.class);
}
/**
* Returns an KBStatus enum which describes whether cycObject
* exists in the KB and is an instance of #$Predicate
.
*
* @param cycObject the CycObject representation of a KB entity
* @return an enum describing the existential status of the entity in the KB
*/
public static KbStatus getStatus(CycObject cycObject) {
return KbObjectImplFactory.getStatus(cycObject, KbPredicateImpl.class);
}
@Override
public Collection getSpecializations() {
return getSpecializations(KbConfiguration.getDefaultContext().forQuery());
}
@Override
public Collection getSpecializations(String ctxStr) {
return getSpecializations(KbUtils.getKBObjectForArgument(ctxStr, ContextImpl.class));
}
@Override
public java.util.Collection getSpecializations(Context ctx) {
//return (this.getValues(Constants.genlPreds(), 2, 1, ctx));
return Constants.genlPreds().getValuesForArgPosition(this, 2, 1, ctx);
}
@Override
public KbPredicate addSpecialization(String moreSpecificStr, String ctxStr) throws KbTypeException, CreateException {
KbPredicate p = KbPredicateImpl.get(moreSpecificStr);
return addSpecialization(p, ContextImpl.get(ctxStr));
}
@Override
public KbPredicate addSpecialization(KbPredicate moreSpecific, Context ctx) throws KbTypeException, CreateException {
Constants.genlPreds().addFact(ctx, moreSpecific, this);
return this;
}
@Override
public Collection getGeneralizations() throws KbException {
return getGeneralizations(KbConfiguration.getDefaultContext().forQuery());
}
@Override
public Sentence getGeneralizationSentence(KbPredicate moreGeneral) throws KbTypeException, CreateException{
return new SentenceImpl (Constants.genlPreds(), this, (Object) moreGeneral);
}
@Override
public Sentence getInverseGeneralizationSentence(KbPredicate moreGeneral) throws KbTypeException, CreateException {
return new SentenceImpl (Constants.getInstance().GENLINVERSEPREDS_PRED, this, (Object) moreGeneral);
}
@Override
public Collection getGeneralizations(String ctxStr) {
return getGeneralizations(KbUtils.getKBObjectForArgument(ctxStr, ContextImpl.class));
}
@Override
public Collection getGeneralizations(Context ctx) {
//return (this.getValues(Constants.genlPreds(), 1, 2, ctx));
return Constants.genlPreds().getValuesForArgPosition(this, 1, 2, ctx);
}
@Override
public KbPredicate addGeneralization(String moreGeneralStr, String ctxStr) throws KbTypeException, CreateException {
KbPredicate p = KbPredicateImpl.get(moreGeneralStr);
return addGeneralization(p, ContextImpl.get(ctxStr));
}
@Override
public KbPredicate addGeneralization(KbPredicate moreGeneral, Context ctx) throws KbTypeException, CreateException {
Constants.genlPreds().addFact(ctx, this, moreGeneral);
return this;
}
@Override
public boolean isGeneralizationOf(KbPredicate moreSpecific, Context ctx) {
try {
return getAccess().getInspectorTool().isGenlPredOf((Fort) getCore(), (Fort) moreSpecific.getCore(), getCore(ctx));
} catch (CycConnectionException e) {
throw new KbRuntimeException(e);
}
}
@Override
public List getExtent() {
return getExtent(null);
}
@Override
public List getExtent(Context ctx) {
final List kbFacts = new ArrayList<>();
try {
final CycList assertions = getAccess().getLookupTool().getPredExtent(this.getCore(), (ctx != null ? getCore(ctx) : null));
for (Object o : assertions) {
if (o instanceof CycAssertion) {
try {
kbFacts.add(FactImpl.get((CycAssertion) o));
} catch (KbTypeException | CreateException e) {
// ignore
}
}
}
} catch (CycConnectionException ex) {
throw new KbRuntimeException(ex);
}
return kbFacts;
}
/**
* Return the KBCollection as a KBObject of the Cyc term that underlies this
* class.
*
* @return KBCollectionImpl.get("#$Predicate");
*/
@Override
public KbObject getType() {
return getClassType();
}
/**
* Return the KBCollection as a KBObject of the Cyc term that
* underlies this class.
*
* @return KBCollectionImpl.get("#$Predicate");
*/
public static KbObject getClassType() {
try {
return KbCollectionImpl.get(getClassTypeString());
} catch (KbException kae) {
throw new KbRuntimeException(kae.getMessage(), kae);
}
}
@Override
String getTypeString() {
return getClassTypeString();
}
static String getClassTypeString() {
return "#$Predicate";
}
// KB API does not do any introspection.. so if we want to use Query API, we should construct
// a fully qualified sentence for the given predicate. That can only be possible when all
// other variables are passed in.
//
@Override
public Sentence getSentence(Object... args) throws KbTypeException, CreateException {
validateArgArity(args);
return new SentenceImpl(this, args);
}
@Override
public Fact getFact(Context ctx, Object... args) throws KbTypeException, CreateException {
final Sentence s = getSentence(args);
return FactImpl.get(s, ctx);
}
@Override
public Boolean isAsserted(Context ctx, Object... args) {
try {
getFact(ctx, args);
return true;
} catch (KbException e) {
return false;
}
}
@Override
public Collection getFacts(Object arg, int argPos, Context ctx) {
try {
final String ctxStr = (ctx == null) ? KbConfiguration.getDefaultContext().forQuery().stringApiValue() //"#$BaseKB"
: ctx.stringApiValue();
final String command = "(" + SublConstants.getInstance().withInferenceMtRelevance.stringApiValue() + " " + ctxStr
+ " (" + SublConstants.getInstance().gatherGafArgIndex.stringApiValue() + " "
+ objectToApiString(arg) + " " + argPos + " "
+ this.stringApiValue() + "))";
LOG.trace("getFacts: {}", command);
final Object res = getAccess().converse().converseObject(command);
LOG.trace("getFacts response: {}", res);
final Set facts = new HashSet<>();
if (!CycObjectFactory.nil.equals(res)) {
final CycList assertList = (CycList) res;
for (Object o : assertList) {
if (o instanceof CycAssertion) {
try {
facts.add(FactImpl.get((CycAssertion) o));
} catch (KbException kbe) {
// Nothing to do. We did get the facts we are building
// but something went wrong. Just don't add it to the list.
LOG.error("Error attempting to get fact {}" + o, kbe);
}
}
}
}
return facts;
} catch (CycConnectionException ex) {
throw new KbRuntimeException(ex);
} catch (CycApiException ex) {
throw new KbRuntimeException(ex.getMessage(), ex);
}
}
@Override
public Fact addFact(Context ctx, Object... args) throws KbTypeException, CreateException {
if (args.length == 2) {
if (args[0] instanceof QuantifiedInstanceRestrictedVariable
|| args[1] instanceof QuantifiedInstanceRestrictedVariable) {
validateArgArity(args);
final List