我正在使用OWL规则在JENA做一个项目。
在我的本体论中,我有一个名为PEGI_RATING
的实体。 PEGI_RATING
可以有多个描述符。
示例:
<http://localhost:2020/PEGI_RATING/6>
a vocab:PEGI_RATING ;
rdfs:label "PEGI_RATING #6" ;
vocab:PEGI_RATING_age
16 ;
vocab:PEGI_RATING_has_PEGI_CONTENT_DESCRIPTOR
<http://localhost:2020/PEGI_CONTENT_DESCRIPTOR/Online> ,
<http://localhost:2020/PEGI_CONTENT_DESCRIPTOR/Violence> ,
<http://localhost:2020/PEGI_CONTENT_DESCRIPTOR/Bad_Language> ;
vocab:PEGI_RATING_ratingId
6 .
现在,我想在OWL中编写一个规则,将年龄附加到每个PEGI_RATING
。我知道它已经存在,但需要证明我知道如何使用推理器。
现在,内容描述符附加了年龄。我按照以下规则执行此操作:
[AgeLimit:
(?descr rdf:type vocab:PEGI_CONTENT_DESCRIPTOR)
(?descr vocab:PEGI_CONTENT_DESCRIPTOR_contentDescriptor "Sex")
->
(?descr vocab:PEGI_CONTENT_DESCRIPTOR_inf_age_limit "16"^^xsd:integer)
]
所以最后我有一个VIDEO_GAME
ID PEGI_RATING
。
例如:
<http://localhost:2020/VIDEOGAME/Grand_Theft_Auto_IV>
a vocab:VIDEOGAME ;
rdfs:label "VIDEOGAME #Grand Theft Auto IV" ;
vocab:VIDEOGAME_EsrbRatingCategoryCategory
<http://localhost:2020/ESRB_RATING_CATEGORY/M> ;
vocab:VIDEOGAME_gameplayRulesGameplayRulesId
<http://localhost:2020/GAMEPLAY_RULES/3> ;
vocab:VIDEOGAME_has_SIDE_GOAL
<http://localhost:2020/SIDE_GOAL/Complete_all_missions.> ;
vocab:VIDEOGAME_onlineMultiplayer
"false"^^xsd:boolean ;
vocab:VIDEOGAME_pegiRatingRatingId
<http://localhost:2020/PEGI_RATING/3> ;
vocab:VIDEOGAME_summary
"For Niko Bellic, fresh off the boat from Europe, it is the hope he can escape his past. For his cousin, Roman, it is the vision that together they can find fortune in Liberty City, gateway to the land of opportunity. As they slip into debt and are dragged into a criminal underworld by a series of shysters, thieves and sociopaths, they discover that the reality is very different from the dream in a city that worships money and status, and is heaven for those who have them and a living nightmare for those who don't." ;
vocab:VIDEOGAME_title
"Grand Theft Auto IV" .
我想创建一个规则,用于确定附加到PEGI_CONTENT_DESCRIPTOR
的{{1}}的{{1}}的最长年龄。
在Prolog中我会做这样的事情:
PEGI_RATING
但是由于OWL似乎没有因失败而被否定,我对如何解决它感到困惑。
到目前为止,我已经尝试了以下规则而没有成功:
VIDEOGAME
所以最后我们有一个工作功能。它确实完成了应该做的事情。然而..
首先,我们有一些Jena格式的规则,为每个 [Age:
(?gameRelease rdf:type vocab:GAME_RELEASE)
(?gameRelease vocab:GAME_RELEASE_videogameTitle ?game)
(?game vocab:VIDEOGAME_pegiRatingRatingId ?pegiID)
(?pegiID vocab:PEGI_RATING_has_PEGI_CONTENT_DESCRIPTOR ?descriptor)
(?descriptor vocab:PEGI_CONTENT_DESCRIPTOR_inf_age_limit ?age)
(?descriptor vocab:PEGI_CONTENT_DESCRIPTOR_inf_age_limit ?age2)
not(lessThan(?age, ?age2))
->
(?game vocab:VIDEOGAME_inf_minimumAge ?age)]
添加一个特定的年龄。这纯粹是出于教学原因(即表明我们可以使用推理器)。这有效。当我添加这些规则时,我可以对我的模型执行SPARQL查询,并获得正确的值。当我写一个模型时(正如Rob Hall在他的例子中所说),[Age:
(?gameRelease rdf:type vocab:GAME_RELEASE)
(?gameRelease vocab:GAME_RELEASE_videogameTitle ?game)
(?game vocab:VIDEOGAME_pegiRatingRatingId ?pegiID)
(?pegiID vocab:PEGI_RATING_has_PEGI_CONTENT_DESCRIPTOR ?descriptor)
(?descriptor vocab:PEGI_CONTENT_DESCRIPTOR_inf_age_limit ?age)
(?descriptor vocab:PEGI_CONTENT_DESCRIPTOR_inf_age_limit ?age2)
greaterThan(?age, ?age2)
->
(?game vocab:VIDEOGAME_inf_minimumAge ?age)]
确实有一个年龄。它们看起来像这样:
PEGI_CONTENT_DESCRIPTOR
请记住,视频游戏的PEGI评分为:PEGI_CONTENT_DESCRIPTOR
。
我们想按如下方式执行Jena Builtin:
<http://local.host.com:2020/PEGI_CONTENT_DESCRIPTOR/Violence>
a vocab:PEGI_CONTENT_DESCRIPTOR ;
rdfs:label "PEGI_CONTENT_DESCRIPTOR #Violence" ;
vocab:PEGI_CONTENT_DESCRIPTOR_contentDescriptor
"Violence" ;
vocab:PEGI_CONTENT_DESCRIPTOR_explanation
"May contain scenes of people getting injured or dying, often by use of weapons, whether realistically or in a fantastical or cartoonish manner. Also may contain gore and blood-letting." ;
vocab:PEGI_CONTENT_DESCRIPTOR_inf_age_limit
18 .
为此,我们有以下功能。它确实有效。但是,由于某些奇怪的原因,?game vocab:VIDEOGAME_pegiRatingRatingId ?pegiId
似乎没有迭代两个特定的minimumPegiAge(?pegiID, ?age)
。即context.find(pegiID, has_descriptor.asNode(), Node.ANY);
和PEGI_DESCRIPTOR
。如上所述,它们存在于推断模型中,并且它们是从SPARQL查询返回的。我们可以处理一个错误吗?或者我们错过了什么?
Sex
答案 0 :(得分:2)
这与现有问题非常相似:Giving array as parameter to jena builtin。在开始之前,注意使用SPARQL查询识别此元素非常容易。
在Jena,您可以实施类似于以下规则:
[Age:
(?game urn:ex:hasRating ?pegiID)
minPegiAge(?pegiID ?age)
->
(?game urn:ex:age ?age)]
开始编辑
规则以一些通用的三元模式开始,而不是使用自定义内置函数(在本例中为minPegiAge
),这一点非常重要。我遇到了一个问题,即提供给我的内置函数的RuleContext
没有从RuleContext#find(...)
返回任何内容。此外,我的规则上下文的InfGraph
(以及Graph
)都是与我的实际InfModel
无关的空图。将规则更改为包含某些通用三元模式作为起始模式后,与InfGraph
关联的RuleContext
与InfGraph
将返回的InfModel
相同。 / p>
结束编辑
这需要您implement a Jena Builtin来计算最小值。在Builtin中,您需要使用可用的RuleContext
来浏览图表,并获得探索最小值所需的内容。以下示例创建一个内置函数,用于提取特定数据类型属性的最小值。
// These properties will be used in the example, I define them for
// convenience here.
final Property hasRating = ResourceFactory.createProperty("urn:ex:hasRating");
final Property age = ResourceFactory.createProperty("urn:ex:age");
// Create and Register a Builtin for Jena's rule system.
BuiltinRegistry.theRegistry.register(new BaseBuiltin() {
@Override
public String getName() {
return "minPegiAge";
}
@Override
public boolean bodyCall( final Node[] args, final int length, final RuleContext context) {
checkArgs(length, context);
final Node rating = getArg(0, args, context);
if( !getArg(1, args, context).isVariable() ){
return false;
}
final Iterator<Node> results =
new NiceIterator<Triple>()
.andThen(context.find(rating, age.asNode(), Node.ANY))
.mapWith(new Map1<Triple,Node>(){
@Override
public Node map1(Triple o) {
return o.getObject();
}});
if( !results.hasNext() ) {
return false;
}
Node min = results.next();
while(results.hasNext()) {
final Node val = results.next();
if( Util.compareTypedLiterals(val, min) < 0 ) {
min = val;
}
}
context.getEnv().bind(getArg(1, args, context), min);
return true;
}
});
// Construct some sample data for this simplified version of
// your example scenario.
final Model rawData = ModelFactory.createDefaultModel();
final Resource game = rawData.createResource("urn:ex:theGame");
final Resource rating = rawData.createResource("urn:ex:theRating");
game.addProperty(hasRating, rating);
rating.addLiteral(age, 15);
rating.addLiteral(age, 14);
// Construct a simplified version of the rule that you use
// in order to identify when the minimum age needs to be
// detected.
final String rules =
"[Age: \n"+
" (?game urn:ex:hasRating ?pegiID) \n"+
" minPegiAge(?pegiID ?age) \n"+
" -> \n"+
" (?game urn:ex:age ?age)]";
final Reasoner reasoner;
try( final BufferedReader src = new BufferedReader(new StringReader(rules)) ) {
reasoner = new GenericRuleReasoner(Rule.parseRules(Rule.rulesParserFromReader(src)));
}
final InfModel inf = ModelFactory.createInfModel(reasoner, rawData);
// Write the model, now including a minimum age triple associated with
// the game rather than the various pe
inf.write(System.out, "TTL");