0

Jena 用の新しいビルトインを作成する必要があります。これで、最小の日付をそこから抽出できるようにしたいと思います。1 つのパラメーターだけでなく、ビルトインにデータのクラスを与えることが可能かどうか疑問に思っています。

これが私の関数の 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)
]

組み込みの 3 つのパラメーターに与えます。入力用に 2 つ、出力用に 1 つ。私のアイデアは、?c と ?d の 2 つの変数を使用することです。どちらにも誕生日があります。?c から最初のレコードを取得し、?d から次のレコードを取得したいと考えています。しかし、イエナは毎回最初のレコードを取るようです。

Javaで、2番目のレコードが必要で、結果をスクロールすることは可能ですか?

たとえば、私のオントロジーは 2 つの日付で構成されています: 1)1992-04-13T00:00:00.0; 2)1988-04-25T00:00:00.0

?c に 1) と ?d に 2) を入れてから、それらの間の最小値を取得するアルゴリズムを作成します。

ps : 上記の「bodyCall」では、ルールに指定した日付間の最大値を取得しようとしています。この目的のためにはうまく機能します。

皆さん、ありがとうございました。

4

1 に答える 1

2

を実装するとき、bodyCall(Node[], int, RuleContext)またはheadAction(Node[], int, RuleContext)実装の一部としてBuiltin、ビルトインへの引数を表す引数の配列が与えられます。ルールでは、任意の数の変数をビルトインに渡すことができます (1 つだけではありません)。

必要なデータを取得するために、クラス式を処理しようとしているようです (質問を誤解している場合は修正してください)。全体的な目標が「データのクラス」を操作することである場合、これを達成する方法は複数あります。

  1. (最も簡単) クラス式をルールの本文内のステートメントとして定式化します。これにより、ビルトインが適切なクラスの個人のみに渡されることが保証されます。複数の前提条件を連鎖させると、特定の個人 (「データのクラス」) に対してのみ操作を行うことができます。

  2. (自明ではない可能性があります) ビルトインで classRuleContextを操作する場合は、渡されたbodyCall(...)orを使用してheadAction(...)、クラス式を満たす個体を (RuleContext#find(...)または他のメソッドを呼び出して) 見つけます。

例として、クラスの各メンバーに作用したいとしましょうurn:ex:Question。最初のソリューションでは、次のようなルールを作成します。

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

これにより、 のすべての単一インスタンスを確実に操作できるようになりますurn:ex:Question。2 番目の解決策の例は、クラス式をビルトインに直接渡すことです。あなたの質問は、問題のクラスをどのように特定するかを示していないため、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 更新の新しい情報に基づいて、おそらく body 呼び出しを次のように変更できます。

@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 に答える