(GNU) Forth Local Variable Behavior - local-variables

I was just learning about local variables for word definitions in Forth. I happen to use GNU Forth (gforth). I was looking at the question and answer, Forth local variable assigning variables and was struggling with the behavior of the given answer. When I tried it, I was getting an underflow unless I had four cells on the stack.
Consider this simple example:
: foo { a b } a b + . ;
This word will take the top two stack cells, store them in the local variables a and b, put a and b (in that order) back on the stack, add them, pop and display the result, and emit a carriage return. It works as I would expect, leaving nothing on the stack when it completes:
: foo { a b } a b + . cr ; ok
1 3 foo 4
ok
.s <0> ok
Now I'd like to try a local variable which is not taken from the stack originally:
: foo { a b | c } a b + to c c . cr ;
I would expect this to behave similarly but use the local variable c. This word would take the top two stack cells, store them in the local variables a and b, put a and b (in that order) back on the stack, add them, pop the result and store it in c, push c back onto the stack, then pop and display the top stack cell and emit a carriage return.
This one doesn't work as I would have expected. Here are my results:
: foo { a b | c } a b + to c c . cr ; ok
1 3 foo
:3: Stack underflow
1 3 >>>foo<<<
Backtrace:
$7F2B572EA1F0 >
Hm, ok, why is there an underflow? Let's try an additional cell on the stack:
1 3 5 foo
:4: Stack underflow
1 3 5 >>>foo<<<
Backtrace:
$7F2B572EA1F8 >l
Still an underflow! Let's try another:
1 3 5 7 foo 4
ok
.s <0> ok
No more underflow. The word foo has consumed all of the cells, but the top two don't appear to be used anywhere. The result 4, which is the sum of the first two cells on the stack, is what I would have expected when I originally tried 1 3 foo.
I have been trying to find some good documentation regarding the local variable behavior, but the manual is very terse on this topic. Can someone explain what is happening here?

Per the comment thread to the question, there is a bug in local variable handling in the "current release", version 0.7.3 (7/9/2014) which has been resolved in a later development release. Downloading, building, and using version 0.7.9_20180319 indicated that the problem was resolved. Thanks to Lars Brinkhoff for pointing out the resolution.

Related

Pylint explanation of R1712

I'm getting this error when using pylint on my project
consider-swap-variables (R1712):
Consider using tuple unpacking for swapping variables You do not have to use a temporary variable in order to swap variables. Using "tuple unpacking" to directly swap variables makes the intention more clear.
and my code is
init_acc_src = acc_src
can some one can explane how should it be done correctly based on pylint?
I think you are swapping variables here, probably we'd need to see more than one line.
I've created a dummy example
a = 5
b = 7
c = a
a = b
b = c
which also raises in line 3 (c=a)
dummy_swap.py:3:0: R1712: Consider using tuple unpacking for swapping variables (consider-swap-variables)
The recommended way of swapping variables in python is the much shorter
a = 5
b = 7
a, b = b, a

NPDA for L= {w ∈ {a,b}*: number of a's is twice the number of b's}

I have been trying to find a NPDA for this language but I can't come up with anything that will accept all of the words in the language. I did try making its accepting condition an empty stack and using the stack alphabet {$ a b} but maybe I should try something else?
Maybe you are looking the equivalent Grammar for the given Regular Expression.
If so maybe this one with the following productions:
S->AAb | SAAb | ASAb | AASb | AAbS
A->a
Some Tests:
aab : S->AAb->aAb->aab
aaaabb : S-> AASb -> AA(AAb)b -> aaaabb
Could check also with other example and see if fit on all cases.
If fine always should have on Result = (2*count_of_b) for a, count_b
Looking twice, A->a can be removed and have only:
S->aab|Saab|aSab|aaSb|aabS
Test:
aaaabb : aaSb(S_4)->aaaabb(S_1), etc.
The context free grammer for number of a's is twice the number of b's is:
S--> aaSb / €(epsilon)
Push down automata can be done for a^2nb^n.push down automata is nothing but the finite automata with memory (can be stack).
Here, for every two a's push one 'a' into the stack and for the input symbol 'b' pop 'a' from the stack.
At the end, if the stack is empty then the string is accepted.
PDA image for a^2nb^n:
δ(q0,a,z0)=(q0,az0)
δ(q0,a,a)=(q1,a)
δ(q1,a,a)=(q0,aa)
δ(q1,b,a)=(q2,ϵ)
δ(q2,b,a)=(q2,ϵ)
δ(q2,ϵ,z0)=(q3,z0)
where,
Q={q0,q1,q2,q3}
Σ=(a,b)
q0=initial state
q3=final state
From the figure for the odd number of a's push into the stack and for even a's skip.Then for each 'b' pop one 'a' from the stack. At the end, an empty stack represents that the string is accepted.

Bash: find all pair of lines such that the difference of their first field is less than a threshold

my problem is the following. I have a BIG file with many rows containing ordered numbers (repetitions are possible)
1
1.5
3
3.5
6
6
...
1504054
1504056
I would like to print all the pair of row numbers such that their difference is smaller than a given threshold thr. Let us say for instance thr=2.01, I want
0 1
0 2
1 2
1 3
2 3
4 5
...
N-1 N
I wrote a thing in python but the file is huge and I think I need a smart way to do this in bash.
Actually, in the complete data structure there exists also a second column containing a string:
1 s0
1.5 s1
3 s2
3.5 s3
6 s4
6 s5
...
1504054 sN-1
1504056 sN
and, if easy to do, I would like to write in each row the pair of linked strings, possibly separated by "|":
s0|s1
s0|s2
s1|s2
s1|s3
s2|s3
s4|s5
...
sN-1|sN
Thanks for your help, I am not too familiar with bash
In any language you can white a program implementing this pseudo code:
while read line:
row = line.split(sep)
new_kept_rows = []
for kr in kept_rows :
if abs(kr[0], row[0])<=thr:
print "".join(kr[1:]) "|" "".join(row[1:])
new_kept_rows.append(kr)
kept_rows = new_kept_rows
This program only keep the few lines which could match the condition. All other are freed from memory. So the memory footprint should remain small even for big files.
I would use awk language because I'm comfortable with. But python would fit too (the pseudo code I give is very close to be python).

Why do tabulate or summarize not take into account missing values when implemented inside a program?

As an illustrative example, suppose this is your dataset:
cat sex age
1 1 13
1 0 14
1 1 .
2 1 23
2 1 45
2 1 15
If you want to create a table of frequencies between cat and sex, you tabulate these two variables and you get the following result:
tab cat sex
| sex
cat | 0 1 | Total
-----------+----------------------+----------
1 | 1 2 | 3
2 | 0 3 | 3
-----------+----------------------+----------
Total | 1 5 | 6
I am writing a Stata program where the three variables are involved, i.e. cat, sex and age. Getting the matrix of frequencies for the first two variables is just an intermediate step that I need for further computation.
cap program drop myexample
program def myexample, rclass byable(recall) sortpreserve
version 14
syntax varlist [aweight iweight fweight] [if] [in] [ , AGgregate ]
args var1 var2 var3
tempname F
marksample touse
set more off
if "`aggregate'" == "" {
local var1: word 1 of `varlist'
local var2: word 2 of `varlist'
local var3: word 3 of `varlist'
qui: tab `var1' `var2' [`weight' `exp'] if `touse', matcell(`F') label matcol(`var2')
mat list `F'
}
end
However, when I run:
myexample cat sex age
I get this result which is not what I expected:
__000001[2,2]
c1 c2
r1 1 1
r2 0 3
That is, given that age contains a missing value, even if it is not directly involved in the tabulation, the program ignores the missing value and does not take into account that observation. I need to get the result of the first tabulation. I have tried using summarize instead, but the same problem arises. When implemented inside the program, missing values are not counted.
You are complaining about behaviour which you built into your own program. The responsibility and the explanation are in your hands.
The effect of
marksample touse
followed by calling up a command with the qualifier
if `touse'
is to ignore missing values. marksample by default marks as "to use" those observations in which all variables specified have non-missing values; the other observations are marked as to be ignored. It also takes account of any if or in qualifiers and any zero weights.
It's also true, as #Noobie explains, that omitting missing values from a tabulation is default for tabulate in any case.
So, to get the result you want you'd need to modify your marksample call to
marksample touse, novarlist
and to call up tabulate with the missing option (if it's compulsory) or to allow users to specify a missing option which you then pass to tabulate.
You also ask about summarize. By design that command ignores missing values. I don't know what you would expect summarize to do about them. It could report a count of missing values. If you want that, several other commands will oblige, such as codebook or missings (Stata Journal). You can always include a report on missings in your program, such as using count to count the missings and display the result.
I understand your program to be very much work in progress, so won't comment on details you don't ask about.
This is caused by marksample. Rule 5 in help mark states
The marker variable is set to 0 in observations for which any of the
numeric variables in varlist contain a numeric missing value.
You should use the novarlist option. According to the help file,
novarlist is for use with marksample. It specifies that missing values
among variables in varlist not cause the marker variable to be set to 0.
if I understand well you want tab to include missing values? If so, you just have to ask for it
tab myvar1 myvar2, mi
from the documentation
missing : treat missing values like other values

Very strange behaviour in the increment of a FOR

I'm having a problem when I use these 2 FOR to initialize a two dimensional vector/array:
I have these types defined:
type
Range9 = 0..8;
Digit = '0'..'9';
Board = array [Range9,Range9] of Digit;
and then the part of the code where there are problems with the FOR's is the following:
var
i : Range9;
j : Range9;
table : Board;
BEGIN
for i:=0 to 8 do begin
for j:=0 to 8 do begin
table[i,j] := '0'
end
end;
END.
Now the problem is that, when I debug this portion of code, for some reason, my i variable is modified when it's not supposed to.
For example, I have a watch on i and j and if I put a breakpoint in the line table[i,j] := 0
I see with the watches these values:
i j
0 0
256 1
512 2
768 3
1024 4
1280 5
1536 6
1792 7
2048 8
2049 8
1 0
257 1
513 2
769 3
and so on...
So, when the program enters in the second for (the one that increases the j) my i increases in intervals of 256... I really don't know why is this happening.
And another thing I discovered is that, the problem solves if I change the TYPE of the i variable.
If in the VAR section I put i : integer instead of i : Range9, i doesn't get modified when isn't supposed to.
I would really appreciate if someone explains me why is happening this.
I've found the answer to my own question... well, I didn't exactly found the answer, I've asked this same question in the forum board of the programming course I'm attending and one of the professors gave me this link:
(it's in spanish btw)
http://www.fing.edu.uy/inco/cursos/prog1/pm/field.php/FAQ/Laboratorio#toc17
A quick translation:
This happens with variables defined as subranges. The reason isn't sure; but without doubt is an implementation error of the debugger. There is a 'trick' that can work to solve this (although not always), to be able to see the correct values on the debugger:
Suppose that you have the following variable in your program:
var anything: 1 .. 10;
Add in your program a integer variable which won't be used in any part of the program:
var anything: 1..10;
aux: integer; { only for the debugger }
Then when you define the debugger watch, instead of adding the anything variable, you should add the following expression:
aux:= anything
The aux variable can be used to view different variables, so you only need to declare one aux variable.
In some cases, the previous may not work. Another solution is to change the type of all the variables defined with subranges to integer, char, string, etc (depending the case) only for debug and the change it back again.
end of the translation.
Hope this will be useful for someone else facing the same error.
BTW, this happens with the debugger of free pascal IDE 2.2.2 , maybe in another IDE/compiler/debugger of pascal it doesn't happen.
I haven't done Pascal in a while, so I might be a bit rusty. The only thing I can think of that is creating your problem is that you created a character range that was interpreted as a byte array, which was then converted to a Digits and then multiplied, which gave you those weird values. But, I could be wrong. I am unfamiliar with FreePascal.
Type
Range9 = 0..8
Board = Array[Range9,Range9] of Integer;
var
A : Board;
I,J : Integer;
begin
For I:=0 to 8 do
For J:=0 to 8 do
A[I,J]:=I*J;
end.
Reference: ftp://ftp.freepascal.org/pub/fpc/docs-pdf/ref.pdf

Resources