Unknown identifiers for ensure block in Eiffel - eiffel

So I'm new to Eiffel programming and I'm trying to learn to write postconditions in the ensure block of a feature, in particular with writing loops.
So I tried this:
feature
-- sets the value of a particular in an array to x
foo (a: ARRAY[INTEGER]; target_val, x: INTEGER)
require
valid_target: 1 <= target_val and target_val <= a.count
do
a[target_val] := x
ensure
across
1 |..| a.count as i
all
across
1 |..| a.count as j
all
i.item /= j.item implies a[i.item] /= a[j.item]
end
end
end
But for some reason I get an unknown identifier for i and j. Does anyone know what causes this error and how I could fix it? Also, is there another alternative to using across ... as ... all ... end in the ensure block? Thanks so much in advance!

I don't know why you get a compilation error - I pasted your code and it compiles fine.
Incidentally, the Eiffel style guidelines say your comment should come AFTER the feature name and arguments, not before it.

As mentioned in another answer, there seems to be no issues with compilation. So, some more information may be required to figure out what's wrong: compiler, its version, etc.
There are at least several alternatives to the example code:
Replace iteration over indexes with iteration over structures themselves:
across a as u all
across a as v all
u.target_index /= v.target_index implies u.item /= v.item
end
end
Write a helper function that will do the necessary tests and return their results as a BOOLEAN.
Add a helper function that iterates over the structure and takes an test agent as an argument, similar to
for_all_with_index (a: ARRAY [BAR]; test: FUNCTION [BAR, INTEGER, BOOLEAN]): BOOLEAN
do
Result := across a as c all test (c.item, c.target_index) end
end
and pass agents that will test items. However, even if it works nice with a single agent, the code with nested mutually dependent agents becomes too heavy.

Related

eiffel: does the across structure move the cursor of current iterable structure?

I was wondering if the across structure uses an own cursor or a separated one? does it ensure that cursor hasn't moved and if so how can it be expressed for other examples?
ITERABLE uses so called external cursors, not internal ones merged with the underlying structure. As a result, iteration affects neither the structure nor any other cursor, created the same way. This is important to support nested or recursive iterations. For example, to find if there are duplicates, one can do the following:
across structure as i loop
across structure as j loop
if i.item = j.item then print ("Duplicates found.") end
end
end
Doing the same with internal cursors, like (note: the code is incorrect)
from structure.start until structure.after loop
x := structure.item
from structure.start until structure.after loop
if x = structure.item then print ("Duplicates found.") end
structure.forth
end
structure.forth
end
does not work, because the inner loop also changes the cursor of the outer loop.
The limitation of the cursors associated with ITERABLE is that the associated structure should not be changed during the whole course of iteration. This is not a theoretical limitation, but a practical one, to simplify implementation and to make it a bit more efficient.

Deep copy always fails in workbench system

I have found one case that does not make sense.
I have following feature:
test_array_deep_copy: BOOLEAN
local
imp, old_imp: ARRAY[STRING]
do
comment("Test of a deep copy.")
create {ARRAY[STRING]} imp.make_empty
imp.force ("Alan", 1)
imp.force ("Mark", 2)
imp.force ("Tom", 3)
old_imp := imp.deep_twin
imp[2] := "Jim"
Result :=
across
1 |..| imp.count as j
all
j.item /= 2 implies imp [j.item] = old_imp [j.item]
end
check not Result end
end
Since it is deep copy, that means address of imp and old_imp are different, as well as that its attributes in both two also refers to different address.
So, this "Result" after across loop, it should be false because addresses in imp and old_imp at same index are different.
So when I debug this code, it say Result is set to be false after finishing across loop.
The problem is that "check not Result" does not make false to true.
If I run workbench system, it says following:
I do not know why. "not" before "Result" in "check not Result" statement should make its whole check true, so it should say "PASSED" in workbench system, but it fails.
why is that?
Your reasoning is correct and the test query as written should return False. Most probably, the system reports FAILED as soon as the query returns False. So, what needs to be done is to fix the query itself.
The items of the array are cloned and therefore the equality = used in the loop gives False for all elements. To get True from the loop, a different equality operator has to be used: ~. It compares objects rather than references. After that change the query gives True and the test should pass.
An alternative would be to replace the equality operator with a call to the feature is_deep_equal:
imp [j.item].is_deep_equal (old_imp [j.item])
Unlike the operator ~ that uses the user-defined feature is_equal to compare objects – strings in the example – is_deep_equal performs "deep" equality test by traversing the whole object tree. The test should pass in this case as well. But deep equality is rarely used in practice.

Please assist in discovering error in MATLAB function

I am taking a MATLAB programming class and we are currently working on a project which uses a database called Project2 of several structs of airline flight data (all 1 x N). One exercise requires us to create a function that identifies the number of flights segments (housed in the flights struct) that used the Boeing 737-800 aircraft. Below I have included the code for the function I created (NOTE: The format of the first line is such that was dictated in the instructions and must remain that way). Although this function seems to work and be free of bugs, it consistently returns a result of 0 and I cannot figure out why. Can anyone help? Suggestions for fixing the problem and/or cleaning up the code would be greatly appreciated!
function total = Problem2 (flights, aircraft, airlines, airports)
load Project2
id=findAircraftID (aircraft, Boeing 737-800)
seg=0;
for jj = 1:length(flights)
if (strcmp (flights(1,jj).aircraft_id, id))
seg=seg+1
end
end
fprintf ('A total of %d flight segments used the Boeing 737-800 aircraft.\n', seg)
end
function id=findAircraftID (aircraft, AircraftName)
id=0;
for ii=1:length(aircraft)
if (strcmp (aircraft(1,ii).name, AircraftName))
id=ii;
return;
end
end
end
Why are you using strcmp to compare integers? Is aircraft_id a string? Perhaps you can cast id from an int to a string if so. Or better yet you can just use isequal(a,b):
if isequal(flights(1,jj).aircraft_id, id)
seg=seg+1;
end
Also see other methods at Octave/MATLAB: How to compare structs for equality?
Also (or alternatively if that's not the issue) you're iterating through your second function and setting id several times, but only the last value goes into the first function. Take a closer look at your for loops to see whether you need to wrap them, store id as an array rather than a single integer, etc.
Never mind I see that your code could work if aircraft names are unique. strcmp should work in that case - but perhaps step through and check that you aren't having issues because of capitalization, spaces, etc.
Usually when you want to find an element in an array that matches a condition, you use something like
bWhenAis3 = B(A == 3);
To find the value of B when A is 3. This can return a vector of multiple values, and is usually much faster than an explicit loop.
In your code, aircraftID is an integer because it's returned by findAircraftID which returns ii. You cannot compare this with a string! You need to compare like types.

In Lua, how should I handle a zero-based array index which comes from C?

Within C code, I have an array and a zero-based index used to lookup within it, for example:
char * names[] = {"Apple", "Banana", "Carrot"};
char * name = names[index];
From an embedded Lua script, I have access to index via a getIndex() function and would like to replicate the array lookup. Is there an agreed on "best" method for doing this, given Lua's one-based arrays?
For example, I could create a Lua array with the same contents as my C array, but this would require adding 1 when indexing:
names = {"Apple", "Banana", "Carrot"}
name = names[getIndex() + 1]
Or, I could avoid the need to add 1 by using a more complex table, but this would break things like #names:
names = {[0] = "Apple", "Banana", "Carrot"}
name = names[getIndex()]
What approach is recommended?
Edit: Thank you for the answers so far. Unfortunately the solution of adding 1 to the index within the getIndex function is not always applicable. This is because in some cases indices are "well-known" - that is, it may be documented that an index of 0 means "Apple" and so on. In that situation, should one or the other of the above solutions be preferred, or is there a better alternative?
Edit 2: Thanks again for the answers and comments, they have really helped me think about this issue. I have realized that there may be two different scenarios in which the problem occurs, and the ideal solution may be different for each.
In the first case consider, for example, an array which may differ from time to time and an index which is simply relative to the current array. Indices have no meaning outside the code. Doug Currie and RBerteig are absolutely correct: the array should be 1-based and getIndex should contain a +1. As was mentioned, this allows the code on both the C and Lua sides to be idiomatic.
The second case involves indices which have meaning, and probably an array which is always the same. An extreme example would be where names contains "Zero", "One", "Two". In this case, the expected value for each index is well-known, and I feel that making the index on the Lua side one-based is unintuitive. I believe one of the other approaches should be preferred.
Use 1-based Lua tables, and bury the + 1 inside the getIndex function.
I prefer
names = {[0] = "Apple", "Banana", "Carrot"}
name = names[getIndex()]
Some of table-manipulation features - #, insert, remove, sort - are broken.
Others - concat(t, sep, 0), unpack(t, 0) - require explicit starting index to run correctly:
print(table.concat(names, ',', 0)) --> Apple,Banana,Carrot
print(unpack(names, 0)) --> Apple Banana Carrot
I hate constantly remembering of that +1 to cater Lua's default 1-based indices style.
You code should reflect your domain specific indices to be more readable.
If 0-based indices are fit well for your task, you should use 0-based indices in Lua.
I like how array indices are implemented in Pascal: you are absolutely free to choose any range you want, e.g., array[-10..-5]of byte is absolutely OK for an array of 6 elements.
This is where Lua metemethods and metatables come in handy. Using a table proxy and a couple metamethods, you can modify access to the table in a way that would fit your need.
local names = {"Apple", "Banana", "Carrot"} -- Original Table
local _names = names -- Keep private access to the table
local names = {} -- Proxy table, used to capture all accesses to the original table
local mt = {
__index = function (t,k)
return _names[k+1] -- Access the original table
end,
__newindex = function (t,k,v)
_names[k+1] = v -- Update original table
end
}
setmetatable(names, mt)
So what's going on here, is that the original table has a proxy for itself, then the proxy catches every access attempt at the table. When the table is accessed, it increment the value it was accessed by, simulating a 0-based array. Here are the print result:
print(names[0]) --> Apple
print(names[1]) --> Banana
print(names[2]) --> Carrot
print(names[3]) --> nil
names[3] = "Orange" --Add a new field to the table
print(names[3]) --> Orange
All table operations act just as they would normally. With this method you don't have to worry about messing with any unordinary access to the table.
EDIT: I'd like to point out that the new "names" table is merely a proxy to access the original names table. So if you queried for #names the result would be nil because that table itself has no values. You'd need to query for #_names to access the size of the original table.
EDIT 2: As Charles Stewart pointed out in the comment below, you can add a __len metamethod to the mt table to ensure the #names call gives you the correct results.
First of all, this situation is not unique to applications that mix Lua and C; you can face the same question even when using Lua only apps. To provide an example, I'm using an editor component that indexes lines starting from 0 (yes, it's C-based, but I only use its Lua interface), but the lines in the script that I edit in the editor are 1-based. So, if the user sets a breakpoint on line 3 (starting from 0 in the editor), I need to send a command to the debugger to set it on line 4 in the script (and convert back when the breakpoint is hit).
Now the suggestions.
(1) I personally dislike using [0] hack for arrays as it breaks too many things. You and Egor already listed many of them; most importantly for me it breaks # and ipairs.
(2) When using 1-based arrays I try to avoid indexing them and to use iterators as much as possible: for i, v in ipairs(...) do instead of for i = 1, #array do).
(3) I also try to isolate my code that deals with these conversions; for example, if you are converting between lines in the editor to manage markers and lines in the script, then have marker2script and script2marker functions that do the conversion (even if it's simple +1 and -1 operations). You'd have something like this anyway even without +1/-1 adjustments, it would just be implicit.
(4) If you can't hide the conversion (and I agree, +1 may look ugly), then make it even more noticeable: use c2l and l2c calls that do the conversion. In my opinion it's not as ugly as +1/-1, but has the advantage of communicating the intent and also gives you an easy way to search for all the places where the conversion happens. It's very useful when you are looking for off-one bugs or when API changes cause updates to this logic.
Overall, I wouldn't worry about these aspects too much. I'm working on a fairly complex Lua app that wraps several 0-based C components and don't remember any issues caused by different indexing...
Why not just turn the C-array into a 1-based array as well?
char * names[] = {NULL, "Apple", "Banana", "Carrot"};
char * name = names[index];
Frankly, this will lead to some unintuitive code on the C-side, but if you insist that there must be 'well-known' indices that work in both sides, this seems to be the best option.
A cleaner solution is of course not to make those 'well-known' indices part of the interface. For example, you could use named identifiers instead of plain numbers. Enums are a nice match for this on the C side, while in Lua you could even use strings as table keys.
Another possibility is to encapsulate the table behind an interface so that the user never accesses the array directly but only via a C-function call, which can then perform arbitrarily complex index transformations. Then you only need to expose that C function in Lua and you have a clean and maintainable solution.
Why not present your C array to Lua as userdata? The technique is described with code in PiL, section 'Userdata'; you can set the __index, __newindex, and __len metatable methods, and you can inherit from a class to provide other sequence manipulation functions as regular methods (e.g., define an array with array.remove, array.sort, array.pairs functions, which can be defined as object methods by a further tweak to __index). Doing things this way means you have no "synchronisation" issues between Lua and C, and it avoids risks that "array" tables get treated as ordinary tables resulting in off-by-one errors.
You can fix this lua-flaw by using an iterator that is aware of different index bases:
function iarray(a)
local n = 0
local s = #a
if a[0] ~= nil then
n = -1
end
return function()
n = n + 1
if n <= s then return n,a[n] end
end
end
However, you still have to add the zeroth element manually:
Usage example:
myArray = {1,2,3,4,5}
myArray[0] = 0
for _,e in iarray(myArray) do
-- do something with element e
end

In Matlab, can I access an element of an array, which is in turn a value of a container.Map?

Here is a code snippet, that shows what I want and the error, that follows:
a = [1, 2];
m = containers.Map('KeyType','char', 'ValueType','any');
m('stackoverflow.com') = a;
pull_the_first_element_of_the_stored_array = m('stackoverflow.com')(1);
??? Error: ()-indexing must appear last in an index expression.
How do I access an element of the array, which is in turn a value of a map object?
I could have done this:
temp = m('stackoverflow.com');
pull_the_first_element_of_the_stored_array = temp(1);
But I do not want to create an intermediate array only to pull a single value out of it.
EDIT : This is a duplicate of How can I index a MATLAB array returned by a function without first assigning it to a local variable? The answer is there.
This is another case where you can get around syntax limitations with small helper functions. EG:
getFirst = #(x)x(1);
pull_the_first_element_of_the_stored_array = getFirst(m('stackoverflow.com'));
This still needs two lines, but you can often reuse the function definition. More generally, you could write:
getNth = #(x, n) x(n);
And then use:
getNth (m('stackoverflow.com'),1);
Although this question is a duplicate of this previous question, I feel compelled to point out one small difference between the problems they are addressing, and how my previous answer could be adapted slightly...
The previous question dealt with how to get around the syntax issue involved in having a function call immediately followed by an indexing operation on the same line. This question instead deals with two indexing operations immediately following one another on the same line. The two solutions from my other answer (using SUBSREF or a helper function) also apply, but there is actually an alternative way to use SUBSREF that combines the two indexing operations, like so:
value = subsref(m,struct('type','()','subs',{'stackoverflow.com',{1}}));
Note how the sequential index subscripts 'stackoverflow.com' and 1 are combined into a cell array to create a 1-by-2 structure array to pass to SUBSREF. It's still an ugly one-liner, and I would still advocate using the temporary variable solution for the sake of readability.

Resources