How to have nested conditions for PMD Xpath rules - xpath

My rule requires me to apply them only to methods without 'get' as part of their name. In another words, my rules need to apply to only non-getter methods in the class. I know to get a hold of all the non-getter methods, I can use
//MethodDeclarator[not(contains(#Image,'get'))]
However, I don't know the syntax about where I insert my logic for the rules. Is it like
//MethodDeclarator[
not(contains(#Image,'get'))
'Some Rule Statements'
]
I saw the use of . in the beginning of statement inside [] in some example code. what are they used for?
In my particular case, I need to combine following pieces together but so far I am unable to accomplish it yet.
Piece 1:
//PrimaryExpression[not(PrimarySuffix/Arguments)]
Piece 2:
//MethodDeclarator[not(contains(#Image,'get'))]
Piece 3:
//PrimaryExpression[PrimaryPrefix/#Label='this']

You need to have at least some basic knowledge/understanding of XPath.
I saw the use of . in the beginning of statement inside [] in some
example code. what are they used for?
[] is called predicate. It must contain a boolean expression. It must immediately follow a node-test. This specifies an additional condition for a node that satisfies the node-test to be selected.
For example:
/*/num
selects all elements named num that are children of the top element of the XML document.
However, if we want to select only such num elements, whose value is an odd integer, we add this additional condition inside a predicate:
/*/num[. mod 2 = 1]
Now this last expression selects all elements named num that are children of the top element of the XML document and whose string value represents an odd integer.
. denotes the context node -- this is the node that has been selected so-far (or the starting node off which the complete XPath expression is evaluated).
In my particular case, I need to combine following pieces together ...
You forgot to say in what way / how the three expressions should be combined. In XPath some of the frequently used "combinators" are the operators and, or, and the function not().
For example, if you want to select elements that are selected by all three provided XPath expressions, you can use the and operator:
//PrimaryExpression
[not(PrimarySuffix/Arguments)
and
PrimaryPrefix/#Label='this'
]

Related

Xpath 1.0: ancestor-or-self::NameTest/NameTest[predicate] does not work as I expect

I am dealing with an XML vocabulary that has "default values": i.e., if a node does not have a certain subnode, I'd like to find the nearest enclosing node that has that subnode, and use its string value as the value of the original node's subnode.
E.g., if I have a tree
Super_node
sub_node: XXX
...
context_node
/* does not have a child with name sub_node */
and no intervening nodes between Super_node and context_node have a child sub_node, I want an expression that evaluates to XXX.
I was thinking that the following query should work, but I always get a node list:
string(ancestor-or-self::*/sub_node[1]/text())
My thinking is that ancestor-or-self::* returns, in reverse document order, the list of context_node, parent_of_context_node, ..., Super_node. I apply the sub_node test to that, and get the list of sub_nodes in that list, again, hopefully, in reverse document order.
I then apply the predicate [1], which should return the first element of that list. However, this predicate seems to be not effective: in my implementation (which I think is based on libxml2), I still receive a list.
What does work, I found after poking around on Stack Exchange a bit, is
string((ancestor-or-self::*/sub_node)[last()]/text())
Why is the predicate [1] above not effective?
The expression
ancestor-or-self::*/sub_node[1]
means
ancestor-or-self::*/(child::sub_node[1])
which selects the first sub_node element child of every ancestor element.
I suspect you were thinking of
(ancestor-or-self::*/sub_node)[1]
which selects all the sub_node children of all the ancestor elements, sorts them into document order, and then returns the first node in this list.
Predicates like [1] bind more strongly than "/".

alloy: arity issue when checking constraint with an assertion

I've recently started to experiment with alloy for a project, and I have run into an issue unequal arities. Here is a simplified example. I have four signatures:
Word
Definition
Document: a document has a text (a sequence of words)
Dictionary: a dictionary maps a sequence of words to a sequence of definitions (to keep it simple, let's say that a word should have exactly one definition)
Here is a minimal code example:
module dictionaries
open util/relation as relation
sig Word {}
sig Definition {}
sig Document {
text: seq Word
}
sig Dictionary {
entries: seq Word,
defseq: seq Definition,
define: Word->Definition,
}{
//dictionary maps word to def only for the word present in dictionary
dom[define] = elems [entries] function [define, elems [entries]]
//content of the list of defintions
defseq = entries.define
}
//assert all word in a dictionary have a definition
assert all_word_defined {
all w: Word | all dict: Dictionary | some def: Definition |
//w in dict.entries implies w->def in dict.define
}
check all_word_defined
So my questions are:
How do I constrain dictionaries so that each word in the dictionary maps to exactly one definition? Is it correct to do it as in the code above?
How do I check that this constraint is respected with an assertion? Obviously the bit of code w in dict.entries implies w->def in dict.define does not work, because w in dict.entriesand w->def in dict.define do not have the same arity, and I get the error message "in can be used only between 2 expressions of the same arity"...
I think you're struggling with seq and assertions more than arity.
seq is not very common in Alloy, you only use it when you need to change the ordering of elements. In this example, I do not see any need for ordering in the current description.
Assertions verify invariants of the whole model. What you try to assert is more a fact that you state in the model than what you assert. Assertions are useful if you have defined operations and want to verify that certain things can never happen regardless of how those operations are executed and in what order. I.e. the assertions verify the consequences of the model, not the facts. (Although sometimes it is useful to verify something in other words.)
Alloy is incredibly powerful in navigating through global tables. Despite looking object oriented, the trick is to understand that fields are actually global tables that are joined. (This is what took me a long time to get.)
You should not have redundant information in the model. You entries, defseq and define can be modelled with functions on the define table.
The base language is very powerful. For a problem of this size you often do not need any utilities. Especially relation seems quite redundant after you feel the relational model of Alloy.
Ok, step by step:
A Documents is a sequence of words:
I would just make a Document a set of Word because that more natural and a lot easier to use. In this problem, the ordering of words does not play a role so using normal sets is ok it seems? (Counting the words would require a seq.)
sig Word {}
sig Document {
text: Word
}
A dictionary maps a sequence of words to a sequence of definitions (to keep it simple, let's say that a word should have exactly one definition)
I think you mean that a Dictionary can map a word to one definition? Does EVERY word have an entry? Or are there some words that have an entry? You say 'a' which I take as some words having one Definition? If so:
sig Definition {}
sig Dictionary {
define : Word -> one Definition,
}
The define table (which is Dictionary->Word->Definition) has a constrain that for a given Dictionary->Word combination, there must be one Definition. This means not all Words have to be in the table, but if a Word is in the table then there must be exactly one Definition. (you can model this also with other constraints. Best is to write out a table and look at the columns.)
You define entries as the set of Word in the Dictionary. You can model this better as a function:
fun Dictionary.entries : set Word {
this.define.univ
}
The first join selects the this Dictionary in the define table and removes the first column. The second join removes the last column.
And similar for defseq:
fun Dictionary.defseq : set Definition {
this.define[univ]
}
The box join [] just joins the inside of the square brackets with the first column of the table before it, leaving the Definition column. That is:
(univ).(this.define)
How do I check that this constraint is respected with an assertion
I think it is not clear what you try to assert. (Which is the power of a formal language that you discover this!) In Alloy you state as a fact that a Word in a Dictionary maps to one Definition. There is no use asserting something you have defined as a fact. Before you can assert you first need more definitions.
Normally you start writing a predicate and then look for examples of your model. For example, if we want to see one of the infinite Dictionary's then we could write:
pred show( d : Dictionary ) {
d.define.univ = Word
}
run show for 5
In this example, you will see a Dictionary where every word has a Definition.
I've written a blog that might be useful for you: http://aqute.biz/2017/07/15/Alloy.html

How do I prevent to operate over an empty matrix or a matrix with empty columns or row?

In the problem that I want to solve a well defined matrix has no empty rows or columns.
For example the matrix [[],[]] is not valid.
When I call the function first_column, how do I prevent to execute it if the matrix that I send as an argument is not valid as defined before?
first_column([],[],[]).
first_column([[H|T]|Tail],[H|Col],[T|Rows]):- first_column(Tail,Col,Rows).
Technically, what you're asking can be done by testing for an end-condition of a list with one element, rather than an empty list, based on the specs you gave.
first_column([[H|T]],[H],[T]).
first_column([[H|T]|Tail],[H|Col],[T|Rows]):- first_column(Tail,Col,Rows).
However, beyond your specs, I suspect that you'll also need to "transfer" your final Col,Rows to end variables, something like:
first_column([[H|T]],C,R,[H|C],[T|R]).
first_column([[H|T]|Tail],[H|C],[T|R],Col,Rows):-
first_column(Tail,C,R,Col,Rows).
The modified predicate would be called with initial conditions, like
first_column(List,[],[],Col,Rows).

how to enumerate array indices as odd and even numbers in parameters part of omnet.ini

I have this parameter as an array. The array is big, 100 cells. It is a parameter that can be initiated in omnet.ini file. The cells with even numbers should get value A and odd numbers should get value B. How can I do this in an automated manner?
Is there a way besides having all odd and even indices initiated one by one manually?
Wildcards can be useful but I do not know how to use them to separate odd and even indices.
Thanks.
You can access the actual module index with the index operator. Combining this with the conditional operator ?: you can easily define the value:
**.myModule[*].myParameter = index % 2 == 0 ? "A" : "B"
I'm not aware of any feature like this. There are a number of work-arounds you could use:
Provide two parameters and select the correct one in code
Use the volatile keyword (probably not appropriate here)
Put the entire thing in your .ini file
I'd personally implement the first approach, that way you can use the wildcard to pass both parameters ([*].myNode.parameterEven and [*].myNode.parameterUneven) and then set the correct values in your array in a for loop.
However, you could also use the volatile keyword in your NED file, see the manual for more details. However, this approach mostly works well if you have different parameters depending on which node you are assigning it to. For this case I think the first approach is better.
The last alternative is just putting the entire thing in your .ini file, which may be useful if you want to parameterize the array later.

XPath to find all following siblings up until the next sibling of a particular type

Given this XML/HTML:
<dl>
<dt>Label1</dt><dd>Value1</dd>
<dt>Label2</dt><dd>Value2</dd>
<dt>Label3</dt><dd>Value3a</dd><dd>Value3b</dd>
<dt>Label4</dt><dd>Value4</dd>
</dl>
I want to find all <dt> and then, for each, find the following <dd> up until the next <dt>.
Using Ruby's Nokogiri I am able to accomplish this like so:
dl.xpath('dt').each do |dt|
ct = dt.xpath('count(following-sibling::dt)')
dds = dt.xpath("following-sibling::dd[count(following-sibling::dt)=#{ct}]")
puts "#{dt.text}: #{dds.map(&:text).join(', ')}"
end
#=> Label1: Value1
#=> Label2: Value2
#=> Label3: Value3a, Value3b
#=> Label4: Value4
However, as you can see I'm creating a variable in Ruby and then composing an XPath using it. How can I write a single XPath expression that does the equivalent?
I guessed at:
following-sibling::dd[count(following-sibling::dt)=count(self/following-sibling::dt)]
but apparently I don't understand what self means there.
This question is similar to XPath : select all following siblings until another sibling except there is no unique identifier for the 'stop' node.
This question is almost the same as xpath to find all following sibling adjacent nodes up til another type except that I'm asking for an XPath-only solution.
This is an interesting question. Most of the problems were already mentioned in #lwburk's answer and in its comments. Just to open up a bit more the complexity hidden in this question for a random reader, my answer is probably more elaborate or more verbose than OP needed.
Features of XPath 1.0 related to this problem
In XPath each step, and each node in the set of selected nodes, work independently. This means that
a subexpression has no generic way to access data that was computed in a previous subexpression or share data computed in this subexpression to other subexpressions
a node has no generic way to refer to a node that was used as a context node in a previous subexpression
a node has no generic way to refer to other nodes that are currently selected.
if everyone of the selected nodes must be compared to a same certain node, then that node must be uniquely definable in a way that is common to all selected nodes
(Well, in fact I'm not 100% sure if that list is absolutely correct in every case. If anyone has better knowledge of the quirks of XPath, please comment or correct this answer by editing it.)
Despite the lack of generic solutions some of these restrictions can be overcome if there is proper knowledge of the document structure, and/or the axis used previously can be "reverted" with another axis that serves as a backlink i.e. matches only nodes that were used as context node in the previous expression. A common example of this is when a parent axis is used after first using a child axis (the opposite case, from child to parent, is not uniquely revertible without additional information). In such cases, the information from previous steps is more precisely recreated at a later step (instead of accessing previously known information).
Unfortunately in this case I couldn't come up with any other solution to refer to previously known nodes except using XPath variables (that needs to be defined beforehand).
XPath specifies a syntax for referring a variable but it does not specify syntax for defining variables, the way how to define variables depends on the environment where XPath is used. Actually since the recommendation states that "The variable bindings used to evaluate a subexpression are always the same as those used to evaluate the containing expression", you could also claim that XPath explicitly forbids defining variables inside an XPath expression.
Problem reformulated
In your question the problem would be, when given a <dt>, to identify the following <dd> elements or the initially given node after the context node has been switched. Identifying the originally given <dt> is crucial since for each node in the node-set to be filtered, the predicate expression is evaluated with that node as the context node; so one cannot refer to the original <dt> in a predicate, if there is no way to identify it after the context has changed. The same applies to <dd> elements that are following siblings of the given <dt>.
If you are using variables, one could debate is there a major difference between 1) using XPath variable syntax and a Nokogiri specific way to declare that variable or 2) using Nokogiri extended XPath syntax that allows you to use Ruby variables in an XPath expression. In both cases the variable is defined in environment specific way and the meaning of the XPath is clear only if the definition of the variable is also available. Similar case can be seen with XSLT where in some cases you could make a choice between 1) defining a variable with <xsl:variable> prior to using your XPath expression or 2) using current() (inside your XPath expression) which is an XSLT extension.
Solution using nodeset variables and Kaysian method
You can select all the <dd> elements following the current <dt> element with following-sibling::dd (set A). Also you can select all the <dd> elements following the next <dt> element with following-sibling::dt[1]/following-sibling::dd (set B). Now a set difference A\B leaves the <dd> elements you actually wanted (elements that are in set A but not in set B). If variable $setA contains nodeset A and variable $setB contains nodeset B, the set difference can be obtained with (a modification of) Kaysian technique:
dds = $setA[count(.|$setB) != count($setB)]
A simple workaround without any variables
Currently your method is to select all the <dt> elements and then try to couple the value of each such element with values of corresponding <dd> elements in a single operation. Would it be possible to convert that coupling logic to work the other way round? So you would first select all <dd> elements and then for each <dd> find the corresponding <dt>. This would mean that you end up accessing same <dt> elements several times and with every operation you add only one new <dd> value. This could affect performance and the Ruby code could be more complicated.
The good side is the simplicity of the required XPath. When given a <dd> element, finding the corresponding <dt> is amazingly simple: preceding-sibling::dt[1]
As applied to your current Ruby code
dl.xpath('dd').each do |dd|
dt = dd.xpath("preceding-sibling::dt[1]")
## Insert new Ruby magic here ##
end
One possible solution:
dl.xpath('dt').each_with_index do |dt, i|
dds = dt.xpath("following-sibling::dd[not(../dt[#{i + 2}]) or " +
"following-sibling::dt[1]=../dt[#{i + 2}]]")
puts "#{dt.text}: #{dds.map(&:text).join(', ')}"
end
This relies on a value comparison of dt elements and will fail when there are duplicates. The following (much more complicated) expression does not depend on unique dt values:
following-sibling::dd[not(../dt[$n]) or
(following-sibling::dt[1] and count(following-sibling::dt[1]|../dt[$n])=1)]
Note: Your use of self fails because you're not properly using it as an axis (self::). Also, self always contains just the context node, so it would refer to each dd inspected by the expression, not back to the original dt

Resources