0

我需要为 Jena 创建一个新的内置插件。有了这个,我希望能够从中提取最小日期。我只是想知道是否可以将一类数据提供给内置而不是一个参数。

这是我的函数的 bodyCall :

         @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 获取下一条记录。但是,看起来耶拿每次都拿第一张唱片。

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

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

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

ps:在上面的“bodyCall”中,我尝试获得我给规则的日期之间的最大值。它可以很好地用于此目的。

谢谢你们。

4

1 回答 1

2

当您实现bodyCall(Node[], int, RuleContext)headAction(Node[], int, RuleContext)作为实现 a 的一部分时Builtin,您将获得一个参数数组,这些参数表示内置函数的参数。通常,您可以将任意数量的变量传递给内置函数(不仅仅是一个)。

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

  1. (最简单)将您的类表达式表述为规则主体中的语句。这将确保您的内置函数仅传递给适当类的个人。将多个先决条件链接在一起可以让您仅对某些个人(“数据类别”)进行操作。

  2. (可能很重要)如果您打算让您的内置函数对一个类进行操作,请使用RuleContext传递给您的bodyCall(...)orheadAction(...)以找到满足您的类表达式的个人(通过调用RuleContext#find(...)或其他方法)。

举个例子,假设我们想对班级的每个成员采取行动urn:ex:Question。在第一个解决方案中,我们将制定类似于以下的规则:

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

这将确保我们对urn:ex:Question. 第二种解决方案的一个示例是将类表达式直接传递给您的内置函数。您的问题并未表明您将如何识别相关课程,因此我将任意假设您对rdfs:subClassOf urn:ex:Question.

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

在这种情况下,您需要以某种方式在内置函数中对“数据类”进行操作。如前所述,您可能会使用RuleContext来执行此操作。

编辑

让我们假设您有 40 个类型为 的个体urn:ex:Question,每个个体都有一个属性urn:ex:dateSubmitted,表明它是何时提交的。这可以使用 SPARQL 查询相当简单地解决:

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

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

@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;
}
于 2014-05-08T20:38:35.957 回答