How to get a CycAccess object? - opencyc

There's a lisp function in ResearchCyc called random-assertion. I want to call that from some Java code. I'm using the Cyc Core API Suite v1.0.0-rc5 (from http://dev.cyc.com), but I don't see any way to call underlying Lisp code.
In the old OpenCyc API there was an object called CycAccess that you could use for this, but I can't figure out how to get one. If I could find it, I'd call this
access.converseObject("(random-assertion)");
At least in ResearchCyc, this would retrieve a pseudo-random assertion from the Cyc knowledge base. Not sure if it would work in OpenCyc, but it might also work there.
Can someone explain how to call lisp-code like this through Cyc's java API?

(Disclaimer: I am one of the developers of the Cyc APIs...)
The reference implementation of the Core API Suite is the Core Client, which is based on the Base Client... which, in turn, is derived from the old OpenCyc API. So, it's absolutely possible to call arbitrary lisp (SubL) code on ResearchCyc, in several different ways...
First of all, there already is a method which wraps random-assertion:
try {
CycAccess access = CycAccessManager.getCurrentAccess();
CycAssertion cycAssertion = access.getLookupTool().getRandomAssertion();
} catch (SessionException ex) {
// Do something with the exception...
} catch (CycConnectionException connEx) {
// Do something else...
}
Speaking to the general case, though, you'll find that the syntax is fairly similar to the OpenCyc API:
try {
CycAccess access = CycAccessManager.getCurrentAccess();
Object cycAssertion = access.converse().converseObject("(random-assertion)");
} catch (SessionException ex) {
// Do something with the exception...
} catch (CycConnectionException connEx) {
// Do something else...
}
Or, if it's safe to assume that the result will be a CycObject:
...
CycAccess access = CycAccessManager.getCurrentAccess();
CycObject cycAssertion = access.converse().converseCycObject("(random-assertion)");
...
However, the Base Client adds a new way of encapsulating SubL functions, via the com.cyc.baseclient.subl.SublFunction interface. The SublFunction interface itself is pretty minimal, but there are a number of classes under com.cyc.baseclient.subl.subtypes which provide implementations for you to extend. For example, if you're calling a no-arg function and expect back a CycObject, you could extend SublCycObjectNoArgFunction like so:
public static final SublCycObjectNoArgFunction RANDOM_ASSERTION_FUNCTION =
new SublCycObjectNoArgFunction("random-assertion");
...
try {
CycAccess access = CycAccessManager.getCurrentAccess();
CycObject cycAssertion = RANDOM_ASSERTION_FUNCTION.eval(access);
} catch (SessionException ex) {
// Do something with the exception...
} catch (CycConnectionException connEx) {
// Do something else...
}
(For other examples of this, see com.cyc.baseclient.subl.functions.* in the Base Client.)
This approach makes it fairly simple to define SubL functions as static fields without writing (or re-writing) much code. We expect the Core Client to gradually migrate towards this approach.
Lastly, you can use the implementation classes in the KB Client to convert your results to KBObjects. For example:
try {
CycAccess access = CycAccessManager.getCurrentAccess();
CycObject cycAssertion = RANDOM_ASSERTION_FUNCTION.eval(access);
// To convert to a com.cyc.kb.Assertion:
Assertion assertion = AssertionImpl.get(cycAssertion);
// Or, to convert to a more general KBObject:
KbObject kbObj = KbObjectImpl.get(cycAssertion);
} catch (SessionException ex) {
// Do something with the exception...
} catch (CycConnectionException connEx) {
// Do something else...
} catch (KbTypeException ex) {
// Potentially thrown by AssertionImpl#get() & KbObjectImpl#get()
} catch (CreateException ex) {
// Also potentially thrown by AssertionImpl#get() & KbObjectImpl#get()
}

Related

Validation with CrudRepository

I'm using HCL cloud.appscan.com and I have Validation.Required warnings on things like this:
Source: com.fasterxml.jackson.databind.ObjectMapper.readValue(String;Class):Object via myclass...
Sink: org.springframework.data.repository.CrudRepository.save(Object):Object via myclass...
In my code I do validate it, but I have no idea how it determines if I am validating the objects before persisting. What code do I need to clear the warnings?
try {
Validate.isTrue(myObject.getMyInt() >= 0);
record.setMyObject(myObject.getMyInt());
save(record);
} catch (Exception e){
// do something
}
You can mark this warning as noise since you are already validating the input. If you really don't want to report this finding during the scan, you can create a validation method and add a #ValidatorMethod (Java) or [ValidatorMethod] (C#) using AppScan annotation library.
For Example
...
isValid(myObject);
record.setMyObject(myObject.getMyInt());
save(record);
...
#ValidationMethod
isValid(YourObject myObject) {
Validate.isTrue(myObject.getMyInt() >= 0);
}

Refactor catch statements

We have many try-catch blocks in our code handling the exceptions of the api calls. Since most of the catch blocks are identical we want to refactor them and only them (because the try blocks should stay in the place they are). How is this possible in Flutter?
Example code:
try {
_userData = apiService.call("user_data");
} on ResourceNotFoundException {
handleResourceNotFoundException();
} on NetworkException {
handleNetworkException();
}
The best solution I found is using a general catch, fit everything into a handleException function, and in there rethrow the exception again.
try {
_userData = apiService.call("user_data");
} on catch (e) {
handleException(e);
}
void handleException(e) {
try {
throw e;
} on ResourceNotFoundException {
handleResourceNotFoundException();
} on NetworkException {
handleNetworkException();
}
}
This way it is possible to reuse the exception handling logic and also extend it.
You should add some abstraction to your API call, meaning you should add a function that takes in the API call you are trying to call as a parameter and surround it with a try-catch block and handle all your exceptions there.
This way you have separated your API calls logic from handling exceptions.

PromiseKit, how to await a finalized promise?

coming from the JS world I'm having a bit of problem wrapping my head around promise kit flavor of promises, I need a bit of help with the following.
Assume I have a function that returns a promise, say an api call, on some super class I await for that promise, then do some other action (potentially another network call), on that parent call I also have a catch block in order to set some error flags for example, so in the end I have something close to this:
func apiCall() -> Promise<Void> {
return Promise { seal in
// some network code at some point:
seal.fulfill(())
}
}
// in another class/object
func doApiCall() -> ? { // catch forces to return PMKFinalizer
return apiCall()
.done {
// do something funky here
}
.catch {
print("Could not do first request"
}
}
now I'm trying to write some unit tests for this functionality, so the response is mocked and I know it will not fail, I just need to await so I can verify the internal state of my class:
// on my test file
doApiCall().done {
// test my code, but I get an error because I cannot pipe a promise that already has a `.catch`
}
How would one go about solving this problem? I could use finally to chain the PMKFinalizer but that feels wrong
Another tangential question would be, is it possible to re catch the error on a higher level, let's say a UI component so it can hold some temporary error state? as far as I see I did not see a way to achieve this.
Many thanks 🙏

Good way to repeat a test, inserting an extra action?

I like the way Catch has nested hierarchies of tests, and it works through the combinations. It feels more natural than the setup/teardown of xUnit frameworks.
I now have a set of tests. What I want to do, about halfway down is insert a load/save serialization test, and then repeat all the tests below that point, first without the load/save, then again using the data it loaded from the serialization process. I.e. to prove that the load/save was correct.
I cannot get my head around if Catch has anything that can help with this? If it was phpUnit, I would be thinking about a string of #depends tests, and use a #dataProvider with a boolean input. A bit ugly.
(If that does not make sense, let me know, and I'll try to work out a minimal example)
The issue here is that Catch is designed to descend a tree-like organisation of tests and it automatically discovers all of the leaf-nodes of the structure and calls back into the test cases with untested code paths until they're all tested. The leaf nodes (tests, sections) are meant to be independent.
It sounds like you want to test a repository - something that can persist some data and then load it back in.
To repeat the exact same tests in two different scenarios (before serialisation, after serialisation) you'd need to put the same tests into some common place and call into that place. You can still use the same Catch macros in a non-test-case function, as long as you call it from a test case.
One possible way to do this is:
struct TestFixture {
Data data;
Repository repository;
TestFixture() : data(), instance() { }
};
void fillUpData(Data& data) {
// ...
}
void isDataAsExpected(Data& data) {
// Verify that 'data' is what we expect it to be, whether we
// loaded it or filled it up manually
SECTION("Data has ...) {
REQUIRE(data...);
}
}
TEST_CASE_METHOD(TestFixture, "Test with raw data") {
fillUpData(data);
isDataAsExpected(data);
REQUIRE(repository.save(data));
}
TEST_CASE_METHOD(TestFixture, "Operate on serialised data") {
REQUIRE(repository.load(data));
isDataAsExpected(_data);
}
One possible alternative is to supply your own main and then use command-line arguments to control whether/not the data is first serialised.
There's a third way I can think of that uses a non-quite-ready-yet feature of Catch - Generators:
TEST_CASE("...") {
using Catch::Generators;
int iteration(GENERATE(values(0, 1)));
const bool doSave(iteration == 0);
const bool doLoad(iteration == 1);
Repository repository;
Data data;
if (doLoad) {
REQUIRE(repository.load(data));
} else {
// fill up data
}
REQUIRE(..data..test..);
if (doSave) {
REQUIRE(repository.save(data));
}
}
The advantage of this method is you can see the flow and the test runs twice (for the two values) but the major disadvantage is that Generators are incompatible with SECTIONs and BDD-style features.

NUnit: Execute code upon assertion failure hook

Is there a hook in NUnit to execute code only when assertion fails without catching the exception itself. Basically, it should accept action delegate to be executed when assertion fails and then re-throw exception. Why do I need this?
I need to compare two objects and dump the result on the screen, for easier debugging, when assertion fails.
Something like this works but is a bad hack, The problem is that it eagerly evaluates ProcessCompareError so I have unnecessary overhead, plus it does it no matter if there is an error or not. So, is there overload that will accept the delegate that would be executed when assertion fails?
Assert.That(benefitLimitComparer.Compare(copyBenefitLimit, origBenefitLimit), Is.EqualTo(0),limitError, ProcessCompareError(origBenefitLimit, copyBenefitLimit));
}
}
}
private string ProcessCompareError(BenefitLimit origBenefitLimit, BenefitLimit copyBenefitLimit)
{
Console.WriteLine("Original: ");
ObjectDumper.Write(origBenefitLimit);
Console.WriteLine("Copy");
ObjectDumper.Write(copyBenefitLimit);
return "";
}
I'm not sure how it might be done through a delegate. One alternative is to store the result of the Compare. If the result is false, write out the contents of the objects and then call Assert.Fail()
There is a possibilty to wrap an assert as an Action in a try-catch. In the catch you can handle the additional compare:
public static void ExecuteAssert(Action assert)
{
if (assert == null) return;
try
{
assert();
}
catch (Exception ex)
{
// perform the compare
}
}
As remark: I use a similar method to continue test execution and avoid the entire test to stop, if some non-fatal checks fail. Actually I iterate through a number of actions:
private static void VerifyAll(params Action[] asserts)