将数组作为参数传递给内置的Jena [英] Giving array as parameter to a Jena built-in

查看:83
本文介绍了将数组作为参数传递给内置的Jena的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要为耶拿创建一个新的内置组件.有了这个,我希望能够从它所在的位置提取最小日期. 我只是想知道是否有可能将一类数据提供给内置数据,而不仅仅是一个参数.

I need to create a new built-in for Jena. With this one I would like to be able to extract the minimum date from where it is. I just wondering if it is possible to give a class of datas to a built-in instead of just one parameter.

这是我函数的bodyCall:

Here is the bodyCall of my function :

         @Override
         public boolean bodyCall(Node[] args, int length, RuleContext context) {
            System.out.println("Entra");
            checkArgs(length, context);
            BindingEnvironment env = context.getEnv();
            Node n1 = getArg(0, args, context);
            Node n2 = getArg(1, args, context);
            //int count = 0;
            //do{
            //System.out.println("RULE"+context.getEnv().getGroundVersion(n2).getLiteralLexicalForm()); count ++;}while(count <2);
            System.out.println("Date 1: " + n1 + " and Date 2: " + n2);
            if (n1.isLiteral() && n2.isLiteral()) {
                Object v1 = n1.getLiteralValue();
                Object v2 = n2.getLiteralValue();
                Node max = null;
                if (v1 instanceof XSDDateTime && v2 instanceof XSDDateTime) {

                    XSDDateTime nv1 = (XSDDateTime) v1;
                    XSDDateTime nv2 = (XSDDateTime) v2;


                    Calendar data1 = new GregorianCalendar (nv1.getYears(), nv1.getMonths(), nv1.getDays());
                    Calendar data2 = new GregorianCalendar (nv2.getYears(), nv2.getMonths(), nv2.getDays());

                    SimpleDateFormat df = new SimpleDateFormat();
                    df.applyPattern("yyyy-dd-MM");

                    if (data1.compareTo(data2) > 0)
                    {
                        System.out.println("la data piu' grande e' DATA1: " +df.format(data1.getTime()));
                        max = args[0];
                    }

                    else
                    {
                        max = args[1];
                        System.out.print("la data piu' grande e' DATA1: " +df.format(data1.getTime()));
                    }

                      return env.bind(args[2], max);
                }
              }
             // Doesn't (yet) handle partially bound cases
             return false;
        }     
    });

这是我的简单规则:

@prefix ex: http://www.semanticweb.org/prova_rules_M#
@prefix rdfs:   <http://www.w3.org/2000/01/rdf-schema#> .
[maxDate:
         (?p rdf:type ex:Persona)
         (?p http://www.semanticweb.org/prova_rules_M/persona#data_nascita ?c)
         (?p http://www.semanticweb.org/prova_rules_M/persona#data_nascita ?d)
         maxDate(?c,?d,?x)
         -> print(?x)
]

我给内置三个参数.两个用于输入,一个用于输出. 我的想法是使用两个变量:?c和?d.他们两个都有生日.我想从?c获取第一条记录,并从?d获得下一条记录.但是,看起来Jena每次都获得第一条记录.

I give to the built-in three parameters. Two for input and one for output. My idea is using two varibles : ?c and ?d. In both of them there is a birthday date. I would like to get the first record from the ?c and the next record from the ?d. But, it looks like that Jena takes each time the first record.

通过Java是否有可能告诉我我想要第二条记录并滚动结果?

Is it possible, by Java, telling that I want the second record and scroll the results ?

例如,我的本体由两个日期组成: 1)1992-04-13T00:00:00.0; 2)1988-04-25T00:00:00.0

For example, my ontology is composed by two dates: 1)1992-04-13T00:00:00.0; 2)1988-04-25T00:00:00.0

我想在?c中有1)在?d中有2),然后制定一种算法来获取它们之间的最小值.

I want to have 1) in ?c and 2) in ?d and then, make an algorithm to get the minimum between them.

ps:在上面的"bodyCall"中,我尝试获取我赋予规则的日期之间的最大值.为此,它工作正常.

ps : In the "bodyCall" above there is my try to get the maximum between to dates that I give to the rule. It works fine for this purpose.

谢谢大家.

推荐答案

当实现bodyCall(Node[], int, RuleContext)headAction(Node[], int, RuleContext)作为实现

When you implement bodyCall(Node[], int, RuleContext) or headAction(Node[], int, RuleContext) as part of implementing a Builtin, you are given an array of arguments that represents the arguments to to the builtin. In a rule, you can hand any number of variables to the the builtin (not only one).

松散地看起来(如果我误解了您的问题,您可以纠正我)您正在寻找一些类表达式以获取所需的数据.如果您的总体目标是对一类数据"进行操作,那么有多种方法可以实现这一目标.

It loosely seems like (and you can correct me if I am misinterpreting your question) that you are looking to work over some class expression in order to get the data that you need. If your overall goal is to operate on 'a class of data', then there are multiple ways to achieve this.

  1. (最简单)将您的类表达式表达为规则主体内的语句.这将确保您的内建函数仅通过适当级别的个人.将多个前提条件链接在一起可以使您仅对某些人(数据类别")进行操作.

  1. (easiest) Formulate your class expression as statements within the body of the rule. This will ensure that your builtin is passed only individuals of the appropriate class. Chaining together multiple preconditions can allow you to only operate on certain individuals (a 'class of data').

(可能不平凡)如果您打算让内置函数在类上运行 ,请使用传递给bodyCall(...)headAction(...)RuleContext来查找满足您的类表达式(通过调用RuleContext#find(...)或其他方法).

(potentially nontrivial) If you intend to have your builtin operate on a class, use the RuleContext passed to your bodyCall(...) or headAction(...) in order to find individuals that satisfy your class expression (by calling RuleContext#find(...) or some other method).

作为一个例子,假设我们要对类urn:ex:Question的每个成员执行操作.在第一个解决方案中,我们将制定类似于以下内容的规则:

As an example, let's say that we wanted to act on each member of the class urn:ex:Question. In the first solution, we'd formulate a rule similar to the following:

[eachIndividual: (?x rdf:type urn:ex:Question) -> builtin(?x)]

这将确保我们可以对urn:ex:Question的每个实例进行操作.第二种解决方案的示例是将类表达式直接传递给内置函数.您的问题并未表明您如何识别所讨论的类,因此,我会随意假定您对rdfs:subClassOf urn:ex:Question的类感兴趣.

This would ensure that we'd operate on every single instance of urn:ex:Question. An example of the second solution would be to pass the class expression to your builtin directly. Your question does not indicate how you would identify the class in question, so I will arbitrarily assume that you are interested in classes which are rdfs:subClassOf urn:ex:Question.

[eachSubclass: (x? rdfs:subClassof urn:ex:Question) -> builtin(?x)]

在这种情况下,您将需要以某种方式对内置的数据类"进行操作.如前所述,您可以使用RuleContext来实现.

In this case, you would need to somehow operate on your 'class of data' within your builtin. As mentioned previously, you could potentially use the RuleContext to do so.

编辑

让我们假设您有40个类型为urn:ex:Question的个人,每个人都有一个属性urn:ex:dateSubmitted,该属性指示提交时间.使用SPARQL查询可以很轻松地解决这个问题:

Let us assume that you have 40 individuals of type urn:ex:Question, and each individual has a property urn:ex:dateSubmitted that indicates when it was submitted. This can be rather trivially solved using a SPARQL query:

SELECT ?post WHERE {
    ?post a urn:ex:Question .
    ?post urn:ex:dateSubmitted ?date .
}
ORDER BY ?date
LIMIT 1

编辑2 根据更新中的新信息,您可能只需修改一下身体调用即可,如下所示:

Edit 2 Based on the new information in your update, you can probably just modify your body call to look like the following:

@Override
public boolean bodyCall( final Node[] args, final int length, final RuleContext context )
{
    checkArgs(length, context);
    final Node n1 = getArg(0, args, context);
    final Node n2 = getArg(1, args, context);

    if (n1.isLiteral() && n2.isLiteral()) {
        final Node max = Util.compareTypedLiterals(n1, n2) < 0 ? n2 : n1;
        return context.getEnv().bind(args[2], max);
    }
    return false;
}

这篇关于将数组作为参数传递给内置的Jena的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆