I have an application wherein I used SPIN constructors as a means to implement Event/Condition/Action (ECA) policies. ECA is one classic construct for policies. The Event, in this case, was always the assertion of a class on an individual which caused that class's SPIN constructors to run on that new individual. The Condition was the pattern expressed in my SPARQL WHERE clause, and the Action was provided by assertions in a SPARQL CONSTRUCT clause. My understanding is that the SPIN constructor would only run on the new individual of the class, not on all individuals of the class.
I'm now looking into switching to SHACL as the successor to SPIN. I'm developing in TopBraid Composer Maestro Edition, and I could implement using the Jena SHACL API.
Suppose that I express an ECA policy as a SHACL shape and target a class via the sh:targetClass SHACL predicate. Let's say my target class is family:Person. Every time I assert a new family:Person individual, I'd like to run my ECA policy (expressed as a SHACL shape) on only that new individual. I'm aware that a listener could be used to sense new class membership. I'm also aware that methods such as RuleUtil.executeRules() could be used once a change is sensed to execute all rules on all targeted nodes (individuals of the family:Person class, in my example). But, is there a way to apply SHACL shapes to only the new individuals of a targeted class? In my application, individuals would be accumulated over time and could become quite numerous. I'm concerned that the computational load of running shapes repeatedly against the same, old, unaltered individuals would become significant.
A possible way to solve your problem is to use a "third-party" relation to mark the individuals that have been processed by the rule, and use such marking in a sh:condition referenced by the rule.
You would obtain something like that:
:MyCondition
a sh:NodeShape ;
rdfs:comment "The condition preventing re-application of the rule";
sh:targetClass :MyClass ;
sh:sparql [
sh:select """
PREFIX : <http://example.com/ns#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
SELECT $this
WHERE {
# Here, the $this will be the focus node of the target class
$this :hasMarking "true"^^xsd:boolean.
}
""";
].
:MyRule
a sh:NodeShape ;
rdfs:comment "The rule should be applied only once";
sh:targetClass :MyClass ;
sh:rule [
a sh:SPARQLRule ;
sh:condition :MyCondition ;
sh:construct """
PREFIX : <http://example.com/ns#>
CONSTRUCT {
$this :hasMarking "true"^^xsd:boolean.
} WHERE {
$this :property :object.
# Here, the body of the rule
# ...
}
""";
].
In this case, the marking is based on a simple boolean property, but it may also be based on a more useful information captured by the rule body, and representative of the rule result, i.e. $this :property :Object, where property is only inferred by your rule.
The concept of "new individuals" sounds application-specific and depends on the execution logic. Nobody forces anyone to use sh:targetClass neither is it required to run all rules all the time. You can control this on API level. Instead of sh:targetClass, you could use some other property of your choice such as ex:constructedClass and implement a Java-based function that takes the new instances as input and follows the property to find all applicable shapes. If you think there is a generic pattern here, we could add them to a de-facto extension namespace such as dash:
Related
I am working with antlr4 to parse some inner language.
The way I do it is the standard way of creating a stream of tokens, then creating a parse tree with set tokens. And the last step is creating a tree.
Now that I have a tree I can use the walk command to walk over it.
The walk command and the parse tree being created are an extension of the BaseListener class.
For my project I use many lookaheads, I mostly use the visitors as a sort of look ahead.
A visitor function can be applied on a node from the parser tree. (Assuming you implement a visitor class)
I have tried creating a smaller listener class to act as my look ahead on a specific node. However, I'm not managing to figure out if this is even possible.
Or is there another / better / smarter way to create a look ahead?
To make the question seem shorter:
Can a listener class be used on a node in the antlr4 parser tree-like visitor can?
There’s no real reason to do anything fancy with a listener here. To handle your example of resolving the type of an expression, this can be done in a couple of steps. You’ll need a listener that builds a symbol table (presumably a scoped symbol table so that each scope in your parse tree has a symbol table and references to “parent” scopes it might search to resolve the data types of any variables.). Depending upon your needs, you can build these scoped symbol tables in your listener, pushing and popping them on a stack as you enter/exit scopes, or you may do this is a separate listener attaching a reference to scope nodes to your parse tree. This symbol table will be required for type resolution, so if you can reference variables in your source prior to encountering the declaration, you’d need too pass your tree with a listener building and retaining the symbol table structure.
With the symbol table structure available to your listener for resolving expression types. If you always use the exit* method overrides then all of the data types for any sub-expressions will have already been resolved. With all of the sub-expression types, you can infer the type of the expression you’re about to “exit”. Evaluating the type of child expressions should cover all of the “lookahead” you need to resolve an expression’s type.
There’s really nothing about this approach that rules out a visitor either, it would just be up to you to visit each child, determining it’s type, and then, at the end of the listener, resolve the expression type from the types of it’s children.
I want to implement a domain specific language using Xtext, and I'm having some trouble with keeping things clean and reusable. Consider the following example:
Spec:
'spec' '(' attrs=AttrAsgnList? ')';
AttrAsgnList:
attrs+=AttrAsgn (',' attrs+=AttrAsgn)*;
AttrAsgn:
name=ID '=' value=INT;
Working with this in Xtend, one would now access the single attributes like this (given a Spec object):
for (a : spec.attrs.attrs) ...
I would much prefer it if I didn't have to go through two levels every time I want to access attributes. The obvious way to prevent this is to inline the whole AttrAsgnList rule into Spec, so that the attrs feature of Spec becomes a list. However, I will need to use constructs like this quite a lot in my DSL, and imo it is bad style to just copy it over and over again.
I am basically looking for a way to directly feed the single AttrAsgn elements into the parent attrs feature. Is that possible or am I stuck with either living with the indirection or bloating everything up by inlining it?
In you case that should be no problem
Spec:
'spec' '(' (attrs+=AttrAsgn (',' attrs+=AttrAsgn)*)? ')';
And no there is no direct way to prevent this copy and pasting
The only chance would be a m2m through IDerivedStateComputer but that would mean you would have elements twice so you would have to clutter the grammar and the metamodel anyway http://xtextcasts.org/episodes/18-model-optimization
The Problem
I have code in F# representing a logical tree. It’s a Business Rules Engine with some fairly simple mathematical functions. I would like to be able to run the rules of the tree many times and see how many times each specific route through the tree is taken.
The requirements are that the base rules should not be changed too much from the simple match statements I’m using at the moment. Tagging the important functions with an attribute would be fine, but adding a call to a logging function at every node is not. I want to be able to run the code in two modes, a highly performant standard mode which just gives answers, and then an “exploratory mode” which gives more detail behind each call. While I don’t mind complicated code to dynamically load and profile the rules, the rules code itself must look simple. Ideally I’d like to not rely on 3rd party libraries - powerpack is ok. The solution must also target the .NET 4.0 runtime.
Potential Solutions
Add a logging call to every function with the function name and arguments. I don’t like this because even if I could disable it in some kind of release mode, it still clutters the rules and means all new code has to be written in an unnatural way.
Each function return its result, and then a list which contains the names of the methods so far called. I don’t like this because it would look unnatural, and would carry a performance hit. I’m sure I could use a computational expression to do a lot of the plumbing, but that violates the requirement to keep the rules simple.
Parse the rules tree using quotations, and then build a new expression which is the old expression with a call to a logging function injected into the site of each tagged function. This is the best thing I’ve got so far, but I’m worried about compiling the resulting quotation so I can run it. I understand (please correct me if I’m wrong) that not all quotations can be compiled. I’d rather not have an unstable process that limits the rules code to a subset of the F# language. If the rules compile, I would like my solution to be able to deal with them.
I know this is a difficult problem with a fairly strict set of requirements, but if anyone has any inspiration for a solution, I would be very grateful.
Edit: Just to give an example of the sort of rules I might be using, if I owned a widget factory producing products A and B the simple following code might be used. I don't want to lose the readability and simplicity of the formulas by adorning this layer with helper functions and hooks.
type ProductType = | ProductA | ProductB
let costOfA quantity =
100.0 * quantity
let costOfB quantity =
if quantity < 100.0 then
20.0 * quantity
else
15.0 * quantity
let calculateCostOfProduct productType quantity =
match productType with
| ProductA -> costOfA quantity
| ProductB -> costOfB quantity
I would like to know what LR-attributed parsers can do and how it is implemented.
yacc generated parsers allow inherited attributes when the source of the attribute is a sibling that is located to the left using the $0, $-1, etc. specification syntax. With S -> A B B would be able to inherit a synthesized attribute from A but would not be able to inherit something from S. I think this is done by looking down 1 element from B in the stack which would be A.
Now zyacc doc says that they allow for LR-attributes grammars which is I guess more or less the same as yacc allows. Only that with zyacc those attributes are specified with the nonterminal (like parameters) and not just accessed within the semantic action. Are there any other difference like LR-attributes are mightier than the yacc inherited attributes or like LR-attributes are implemented differently (not just looking down the stack).
The point of LR attributed grammars is to make information seen in the left context,
available to the right extension.
Imagine your grammar had
R -> X S Y;
S -> A B;
You've already agreed that S can see attributes synthesized from X. In fact, those attributes can be available on the completion of parsing of X. Done properly, those attributes should be available to A and B, as they are parsed, as inherited attributes from S.
YACC doesn't implement any of this to my knowledge, unless you want to count the existence of the parse tree for X as being a "synthesized" attribute of parsing X.
How you implement attributed grammars depends on what you want to do. My company's main product, DMS, uses attribute grammars heavily, with no direction constraints. We simply build the full tree and the propagate the attributes as needed.
What we do is pre-compute, for each node type, the set of attributes [and their types] it may inherit, and the set it may synthesize, and synthesize a struct for each. At attribute evaluation time, these structs are associated with tree nodes via a very fast access hash table. For each node type, we inspect the dataflows (which child consumes which inherited attribute, which children use synthesized attributes from which other children). From that we compute an order of execution to cause all the attributes to be computed in a safe (generated-before-consumed) order and generate a procedure to accomplish this for that node type, which calls children procedures. Attribute evaluation then consists of calling the generated procedure for the grammar root. (In fact, we actually generate a partial order for evaluating the children, and generate a partial-order parallel call using DMS's implementation parallel programming language's capabilities, ensuring fast evaluation using multiple cores on very big ASTs).
There isn't any reason you couldn't limit this process to LR attributes. (Someday we'll push LR-compatible attributes into the parsing phase to allow their use in semantic checks).
It shouldn't surprise you that the device that generates the attribute evaluation process, is itself an attribute-evaluator that operates on grammars. Bootstrapping that was a bit of fun.
I have been trying out ilog jrules for sometime now.I especially interested in rule overriding feature, though there is pure IRL way to create heirachies and override the rules programatically. I want to use rule studio for rule overriding rather than writing it in IRL.
In rule property window of rule studio,there is an option to specify a rule which is to be overriden, but I do not find any places to give the conditions which is used to make the overriding decision for the rules.
Can anyone throw some light on this ? Where do I add the conditions which are used to override the rules ? Or do I have to do it in the IRL programmatic way itself ?
A rule can override one or more other rules if these rules are selected in the same rule task at run time.
Let's say you have the two rules A & B. A is a rule granting you a general discount if you have reached gold status in the loyalty program:
Rule A:
if
the status of 'the customer' is gold
then
add a 4% discount, reason: "Gold membership"
Rule B should override this rule for the German market with a discount of 5%:
Rule B:
if
the status of 'the customer' is gold
and the home country of 'the customer' is Germany
then
add a 5% discount, reason: "German loyalty program: gold status"
The property of Rule B has to specify that Rule A should be overridden (In the properties: overridden rules: [Rule A]). In case both rules can be executed, only Rule B is selected because of the "overridden rules" property. Rule A will be overridden, which means that both rules are selected in the same rule task at run time.
For more information take a look at the documentation