eval() is not working properly - alloy

I get the following error while trying to evaluate a predicate in a a4solution:
Fatal error in /some/path at line 9 column 2: Field "field
(A/Attribute <: type)" is not bound to a legal value during
translation.
Here is the code at the origin of the error:
for(ExprVar a : solution.getAllAtoms()){
// additional checks are here to assure that a is of an "appropriate type"
solution.eval(predicate.call(a));
}
In my vain attempts to solve this problem by myself, I read from this source http://code.google.com/p/alloy4eclipse/issues/detail?id=86 that the way the solution has been read from the file might cause this problem.
But the source doesn't give further details.
I have created my solution object as follows :
XMLNode xml = new XMLNode(new StringReader(source.getFileContent()));
this.solution = A4SolutionReader.read(new ArrayList<Sig>(), xml);
Thank you for your support

The problem was that the expression to be evaluated (predicate.call(a)) was drawn from one CompModule object (namely the predicate function was taken from there) while the solution object, against which the expression was evaluated, was not obtained from the same CompModule, but was read from a file.
Generally, when reading a solution from an xml file, to be on the safe side, it is recommended to reread and reconstruct everything from that xml file, e.g.,
XMLNode xmlNode = new XMLNode(new File("my_solution.xml"));
String alloySourceFilename = xmlNode.iterator().next().getAttribute("filename");
Module module = CompUtil.parseEverything_fromFile(rep, null, alloySourceFilename);
A4Solution ans = A4SolutionReader.read(module.getAllReachableSigs(), xmlNode);
In some cases it suffices to just pass the sigs from the original CompModule to the reconstructed solution:
XMLNode xmlNode = new XMLNode(new File("my_solution.xml"));
A4Solution ans = A4SolutionReader.read(originalModule.getAllReachableSigs(), xmlNode);

Related

IBM Doors DXL: can't iterate over objects in module

I have a rather peculiar problem with IBM Doors, using its DXL language:
I CAN get a variable to the module I want to access:
our_mod = module "<path_including_filename_of_module>"
I can NOT perform any of the usual functions pertaining to modules on that variable, e.g.:
name (our_mod) //or entering the string consisting of path + filename directly)
it gives me the error output: "incorrect arguments for fucntion (name)"
BUT, if I search through the folder containing the module, I can grab it via its filename:
Item x
Item my_module
for x in my_folder do
{
if (name(x) == "<filename>")
{
my_module = x
}
}
THEN I can perform name(my_module) or type (my_module):
returns the filename and "Formal" as expected
But even if I get the module that way, I still can NOT iterate over the objects inside that module like with
Object o
for o in my_module do // ...in all my_module... does not work either, same error msg
{
//Do what I came to do...
}
It just gives me the error message "incorrect arguments for (do)"
If anybody had any idea whatsoever as to what might be causing this, would be much obliged.
thanks and regards
There are several data types in DXL that have something to do with modules, all of them have different access functions (perms). E.g. variables of type Item are good for iterating over "everything in a folder or project". If you want to iterate over objects, you need a variable of type Module. As you already found out, the perm "module (string)" does NOT return data of type Module. It returns either a variable of type bool or of type ModName_ (which is a module reference, not a module), depending on the data type where you assign the result. For details, see e.g. the perms list on Tony Goodman's page at http://www.smartdxl.com/downloads/undoc31.html.
In DXL, make sure that you ALWAYS declare variables with a type, never use Auto-Declare if you want to keep your sanity (if you say print our_mod in your upper example you will find that you got a bool, which of course has neither a name nor a type).
For getting a variable of type Module, you first need to open the module (like in real life :) :)). You can open it using edit, share or read. E.g. like this
Module m = read ("/path/to/my_mod", false /* display */, true /* load standard view */)
if null m then error "could not open the module"
Object o
for o in entire m do {print o."Absolute Number" ""}
close m

How can I call this jOOQ generated function taking a custom bound type?

I originally had the following SQL function:
CREATE FUNCTION resolve_device(query JSONB) RETURNS JSONB...
and the following code calling the method generated by jOOQ:
final JsonArray jsonArray = jooqDWH.select(resolveDevice(queryJson)).fetchOne().value1().getAsJsonArray();
final JsonObject o = jsonArray.get(0).getAsJsonObject();
This worked fine. I needed to return a real device object rather than a JSON blob though, so I changed the SQL function to:
CREATE FUNCTION resolve_device(query JSONB) RETURNS SETOF device...
and the code to:
final ResolveDeviceRecord deviceRecord = jooqDWH.fetchOne(resolveDevice(queryJson));
but I am getting a runtime error:
org.jooq.exception.SQLDialectNotSupportedException: Type class com.google.gson.JsonElement is not supported in dialect DEFAULT
Many other parts of my code continue to work fine with the custom binding I have converting JsonElement to JSONB, but something about the change to this function's signature caused it to stop working.
I tried a few different variants of DSL.field() and DSL.val() to try to force it to be recognized but have not had any luck so far.
This could be a bug in jOOQ or a misconfiguration in your code generator. I'll update my answer once it is clear what went wrong.
Workaround:
Meanwhile, here's a workaround using plain SQL:
// Manually create a data type from your custom JSONB binding first:
final DataType<JsonObject> jsonb = SQLDataType.OTHER.asConvertedDataType(jsonBinding);
// Then, create an explicit bind variable using that data type:
final ResolveDeviceRecord deviceRecord =
jooqDWH.fetchOptional(table("resolve_device({0})", val(queryJson, jsonb)))
.map(r -> r.into(ResolveDeviceRecord.class))
.orElse(null);

Issues adding source code to a custom DSL file programatically

I currently have a xtext grammar that looks like the following :
Features:
'feature' name = ID
'{'(
('action' '{' action+=Actions (',' action+=Actions)* '}')? &
('dependencies' '{' dependencies = Dependencies '}')? &
('children' '{' children = Children '}')?
)'}'
;
What I want to do with this is add an action to an already existing source file programatically, for that I am using the IUnitOfWork.Void class that I subclass for easier implementation , it currently looks like this (the meaningful part of it) :
final XtextEditor editor = (XtextEditor)sourcepart;
final IXtextDocument document = editor.getDocument();
document.modify(new IUnitOfWork.Void<XtextResource>(){
public void process (XtextResource resource) throws Exception {
IParseResult parseResult = resource.getParseResult();
if(parseResult ==null)
return;
CompositeNode rootNode=(CompositeNode) parseResult.getRootNode();
LeafNode node = (LeafNode)NodeModelUtils.findLeafNodeAtOffset(rootNode, 0);
EObject object =NodeModelUtils.findActualSemanticObjectFor(node);
Through this I traverse the tree of the model and get to my Features object to which I want to add an action to (this is done through a pop up menu in a custom Tree View I'm implementing)
Here's my problem : whenever I want to add an action it screws up the way the tags are placed in the source file , and by that I mean that instead of :
action {
act1.set (foo),
act2.set (bar),
act3.set (baz),
act4.set (booze) //where this is the new action that I add
}
it will add it as
action {
act1.set (foo),
act2.set (bar),
act3.set (baz)
}
action {
act4.set(booze)
}
And this is illegal by the rules of my grammar, and I'm not allowed to change the way it should be written. (I am allowed to make small changes to the way the rules are implemented, but would really want to avoid it as it would mean a whole new amount of work to reimplement other things that depend on them)
I've tried :
adding it directly through Features.getAction().add(*the new action);
copying the items in the list into an array with the toArray() method so as to avoid referencing, adding my action to the array, clearing the list then adding all the elements again one by one
creating an entirely new Features object and setting everything in it to be the same as the currently edited one then replacing the feature with the new one
And I'm out of ideas after that. The frustrating part is that the 3rd method worked for a different kind of object in my grammar and had no errors there.
How could I make this work ?
this is a bug in xtext. (can you please file a ticket?)
as a workaround you may use the following
Features:
'feature' name = ID
'{'(
('action' '{' actionList=ActionList '}')? &
('dependencies' '{' dependencies = Dependencies '}')? &
('children' '{' children = Children '}')?
)'}';
ActionList:
(action+=Action (',' action+=Action)*)
;

C#/ Html Agility pack error "Value cannot be null. Parameter name: Source."

I've used html agility pack before, and have had good results with a little bit of trial and error. I'm currently trying to use it to return a node set with an xpath I get by right- clicking "Copy XPath" in Firefox. I've done some searching, and I see that the browser will often add "tbody" for table tags. I tried it with removing this with no luck. Here is the xpath given to me by Firefox:
/html/body/p[3]/table/tbody/tr/td/table/tbody/tr[3]
Using it as- is throws the error: "Value cannot be null. Parameter name: source."
This occurs on line:
nodeList = htmlDoc.DocumentNode.SelectNodes("/html/body/p[3]/table/tbody/tr/td/table/tbody/tr[3]").ToList();
I'll continue to read, in the meantime if this is an easy fix to anyone, I'd appreciate a tip.
Update: This is the actual code:
protected override List<IDataPoint> ReturnDataPointsFromIndividualAddressString(string AddressString)
{
List<IDataPoint> earningsAnnouncements = new List<IDataPoint>(); //Not used, yet..
HtmlWeb hwObject = new HtmlWeb();
HtmlDocument htmlDoc = hwObject.Load(AddressString);
if (htmlDoc.DocumentNode != null)
{
List<HtmlNode> nodeList = new List<HtmlNode>();
nodeList = htmlDoc.DocumentNode.SelectNodes("/html/body/p[3]/table/tbody/tr/td/table/tbody/tr[3]").ToList();
}
}
It seems this error occurs on this line:
nodeList = htmlDoc.DocumentNode.SelectNodes("/html/body/p[3]/table/tbody/tr/td/table/tbody/tr[3]").ToList();
The thing is, if SelectNodes method doesn't find nodes by xpath expression passed it returns null. You could find more information in this answer to a similar question HTML Agility Pack Null Reference. And then you call a ToList() method on a null object which is actually causes an NullReferenceException.
To avoid this check the this variable against null like this:
var nodes = htmlDoc.DocumentNode.SelectNodes(...);
if (nodes != null)
{
nodeList = nodes.ToList();
}

Reading/Editing XLIFF using C#

I need to parse an XLIFF file using C#, but I'm having some trouble. These files are fairly complex, containing a huge amount of nodes.
Basically, all I need to do is read the source node from each trans-unit node, do some processing on it, and insert the processed text into the corresponding target node (which will always be present, but empty).
An example of one of the nodes I need to parse would be (the whole file may contain 100s of these):
<trans-unit id="0000000002" datatype="text" restype="string">
<source>Windows Update is not installed</source>
<target/>
<iws:segment-metadata tm_score="0.00" ws_word_count="6" max_segment_length="0">
<iws:status target_content="placeholders_only"/>
</iws:segment-metadata>
<iws:boundary-seg sequence="bs20721"/>
<iws:markup-seg sequence="0000000001">
</trans-unit>
The trans-unit nodes can be buried deep in the files, the header section contains a lot of data. I'd like to use LINQ to XML to read the data, but I'm not having any luck getting it to work. Here's my current code (just trying to read and output the source nodes from the file:
XDocument doc = XDocument.Load(path);
Console.WriteLine("Before loop");
foreach (var transUnitNode in doc.Descendants("trans-unit"))
{
Console.WriteLine("In loop");
XElement sourceNode = transUnitNode.Element("source");
XElement targetNode = transUnitNode.Element("target");
Console.WriteLine("Source: " + sourceNode.Value);
}
I never see 'In loop' and I don't know why, can someone tell me what I'm doing wrong here, or suggest a better way to achieve what I'm trying to do here?
Thanks.
Try
XNamespace df = doc.Root.Name.Namespace;
foreach (XElement transUnitNode in doc.Descendants(df + "trans-unit"))
{
XElement sourceNode = transUnitNode.Element(df + "source");
// and so one, use the df namespace object to qualify any elements names
}
See also http://msdn.microsoft.com/en-us/library/bb387093.aspx.

Resources