Implementing if statements - turing-complete

I created my own programming language that compiles down to Turing Machine instructions and I was wondering how to implement if(a>b) do _ end. Here's the definition of the language(also available here)
Variables are dynamically allocated at any width so can have arbitrarily large integers
Each line can do one of three things, it can call a function(which modifies it's argument), start a while loop(which is really more of a for loop), or assign a variable.
The available functions are incr(Increment by one, can overflow), decr(Decrement by one, can overflow), pop(Remove the last digit from a variable), first(Changes the most significant 0 in a variable to 1), and frost(changes the most significant 1 to a zero).
A while loop has the following syntax,
while a <func> {
_
}
Basically every time it loops it does <func> to a till error condition. The error conditions are as follows, incr and first has all 1's, decr and frost has all 0's, pop removes the last digit. After a while loop with incr or frost all bits of the looping variable will be 0, opposite with first and decr. While loops have to end on a function call, and they delete all variables contained within after each run.
Assignment can do a few different things based on the syntax. a=b means copy variable b into the space owned by variable a if b is longer than a this causes undefined behavior unless a is the latest variable created. a=b,5 assigns b to a with five padding bits(set to zero) to the left, again overflows cause undefined behavior unless a is the latest variable created. a=a,0 zeroes out a. Finally a=5,3 will assign 5 % 2**3 to a in 3 bits.
Now I can implement if(a != 0) do _ end with
while a decr {
_
t=0,1
while a incr {
incr(t)
}
incr(t)
}
My question is how can I implement the other if statements, like if(a==b), if(a!=b), and if(a>b)
And as a secondary question is this language Turing Complete, I believe so based on this answer Are there minimum criteria for a programming language being Turing complete?. I know the language satisfies 1 through 5, but I'm not sure about 6.

(please let me know if i've assumed wrong about the loop or incr/decr behavior, that would alter my answer)
Your original code for if(a!=0) appears to loop forever. As it is, it's doing while(a) do _ end because it either loops indefinitely or not at all. Lastly t would not exist outside of the loop and does not appear to be utilized inside it, even though it looks like the value you're trying to capture (true/false on the comparison).
You don't have a comment syntax so i'll throw in // comment / c-style comments where needed.
Maybe something like this...
if (a > 0) do _ end
// if (a > 0) do _ end
_a = a
while _a decr {
// overflow iif _a= 0
_ // do something
_a = 0
frost( _a ) // only function calls at end of loops
}
if (a == 0) do _ end
// if (a == 0) do _ end
_a = a
result = 1,1
while _a decr {
// overflow iif _a= 0
_a = 0
frost( result ) // only function calls at end of loops
}
while result decr {
// overflow iif result = 0
_ // do something
frost( result ) // exit loop
}
The pattern is straightforward for a non-zero check as you've noticed - decrement it, and if you didnt overflow (underflow technically) then you're dealing with something that was 1 or greater. Trick is exiting the while, which you can do by using a decr test and setting the variable being tested to 0 upon exit. For this, your frost function is suitable because for a target variable of 0 it leaves the result unmodified, and a target of 1 becomes 0 such as in result's usage.
Your documentation says that a function must mark the end of a loop, not an assignment or another loop, but your own examples are inconsistent with this, just to note.
I'm making an example for the remaining test conditions: a > b and a == b; the others can be derived from just these two and logical inversion / not operator, which you've seen in the above using result.
if (a == b) do _ end
// if( a == b ) do _ end
a_cond = a
b_cond = b
// step 1: a_cond = a - b
while b_cond decr {
decr(a_cond)
}
// step 2: if (a_cond == 0)
result = 1,1
while a_cond decr {
// overflow iif a_cond = 0
a_cond = 0
frost( result ) // only function calls at end of loops
}
while result decr {
// overflow iif result = 0
_ // do something
frost( result ) // exit loop
}
if (a > b) do _ end
WIP. will be similar to (a==b) case

Related

Is it possible to model arrays as functions while preserving O(1) access times?

It is quite easy to model linked-lists as functions, without any underlying collection data type, like so:
-- This is Lua code, but the specific language shouldn't matter
function createList(first, rest)
return function(isFirst)
if isFirst
then
return first
else
return rest
end
end
end
function nth(list, n)
-- replace with n==0 for 0 indexing,
if (n == 1)
then
return list(true)
else
return nth(list(false), n-1)
end
end
However, this has the disadvantage when compared to arrays that index access has O(n) time complexity. I had been thinking that array literals would be easy to implement thusly:
-- {1, 2, 4, 8} ==
function someArray(n)
if (n == 1)
return 1
elseif (n == 2)
return 2
elseif (n == 3)
return 4
elseif (n == 4)
return 8
end
end
But I realized that going through each elseif one at a time would still be access time O(n). I considered a switch statement, as I was under the impression that C's switch statements jumped directly to the tag that matches the result of the condition, but this does not appear to be correct. It appears that with n branches, C's switch selects a branch in O(n) time. Is it possible to select a branch in constant time without using arrays? Is there some other technique for a constant time access to an array modelled as a function that I have missed?

Could someone explain me what does this line of code mean?

I was wondering what this code really means. I mean, I would like to know what it does, in what order, and what do ? and : signs mean; all explained.
printf(" %c", ((sq & 8) && (sq += 7)) ? '\n' : pieces[board[sq] & 15]);
Thanks.
The first argument, " %c", means that printf needs to print out a character.
The second argument is the character that the function prints.
In this case, the second argument is a ternary operator. You can read the link provided, but in short, it's basically a short-hand for an if-else block. This is what it looks like in your example:
((sq & 8) && (sq += 7)) ? '\n' : pieces[board[sq] & 15]
Let's separate it into three parts:
((sq & 8) && (sq += 7))
'\n'
pieces[board[sq] & 15]
The first part is a condition (if);
this expression (sq & 8) uses what is called a bitwise AND operation (read more here). Basically, 8 in binary is 1000 and that part checks whether sq has a 1 in that position (it can be 1000, 11000, 101000 etc.); if it does, that expression equals 8 (any number bigger than zero means true) and if it doesn't, it equals 0 (which means false).
&& means AND, it just means that both left and right expression need to be true
sq += 7 will add 7 to sq and if it's not 0, it is true.
The second part \n is returned (and in your case printed out) if the condition is true; else the third part will be printed out (pieces[board[sq] & 15]).
This is fairly obfuscated code, so it's best to try to understand it in the context in which it appears. By obfuscating it in this way, the auther is trying to tell you "you don't really need to understand the details". So lets try to understand what this does from the 'top down' inferring the details of the context, rather than bottom up.
printf prints -- in this case " %c", which is a space and a single character. The single character will either be (from the ?-: ternary expression)
a newline '\n'
a piece from space sq on the board
which it will be depends on the condition before the ? -- it first tests a single bit of sq (the & 8 does a bitwise and with a constant with one set bit), and if that bit is set, adds 7 to sq and prints the newline1, while if it is not set, will print the piece.
So now we really need to know the context. This is probably in a loop that starts with sq = 0 and increments sq each time in the loop (ie, something like for (int sq = 0; ...some condition...; ++sq)). So what it is doing is printing out the pieces on some row of the board, and when it gets to the end of the row, prints a newline and goes on to the next row. A lot of this depends on how exactly the board array is organized -- it would seem to be a 1D array with a 2D board embedded in it; the first row at indexes 0..7, the second at indexes 16..23, the third at indexes 32..39 and so on2.
1technically, when the bit is set, it tests the result of adding 7, but that will be true unless sq was -7, which is probably impossible from the context (a loop that starts at 0 and only increments from there).
2The gaps here are inferred from the test in the line of code -- those indexes with bit 3 set (for which sq & 8 will be true) are not valid board spaces, but are instead "gaps" between the rows. They might be used for something else, elsewhere in the code
Ok, thank you all! I've looked at it and it now works as expected. Thanks!

Using vectorization to reduce for loops, how to use conditional if?

I'm working in a Matlab project and I have a function that is working, but I want to optimize it, reducing the number of for loops that I have in my code.
I read about vectorization, I could use it but how would I include the if conditional statement if I have to test every single value at a time?
function [y, zf] = MyFunction(x, b, zi)
y = zeros([length(x) 1]);
for n = 1:length(x)
for k=1:length(zi)
if n<k
y(n) = y(n) + b(k)*zi(length(zi)+(n-k)+1);
else
y(n) = y(n) + b(k)*x(n-k+1);
end
end
end
zf = x(length(x)-length(zi)+1:length(x));
I manage to do the vectorization, but I can't figure how to do the conditional, I get the warning:
Variable 'n' might be set by a nonscalar operator
function [y, zf] = MyFunction(x, b, zi)
y = zeros([length(x) 1]);
n=1:1:length(x); % use of vectorization
for k=1:length(zi)
if n<k % problem with if
y = y + b(k)*zi(length(zi)+(n-k)+1);
else
y = y + b(k)*x(n-k+1);
end
end
zf = x(length(x)-length(zi)+1:length(x));
Currently n is a vector and k is a scalar, and n<k returns a logical vector. If you directly use if, it would be the same as if all(n), which will only return true when everything in that vector is true! That's unexpected behavior.
I don't know if there's a general way to vectorize codes with if. But in your case, I can do it this way.
% use indice to deal with if
for k=1:length(zi)
y(1:k-1)=y(1:k-1)+b(k)*zi(length(zi)+2-k:end);
y(k:end)=y(k:end)+b(k)*x(1:length(x)-k+1);
end
I also notice that actually if you cat zi and x, it's no need to use 2 individual statement.
% assume both zi & x to be column vector
ziandx=[zi;x];
for k=1:length(zi)
y=y+b(k)*ziandx(length(zi)+2-k:length(zi)+length(x)-k+1);
end
Finally, even this for-loop is no need if you use conv. (check the doc for more detail)
ziandx=[zi;x];
s=conv(b(1:length(zi)),ziandx);
y=s(length(zi)+1:length(zi)+length(x))
I recommend you to read all three methods and understand the idea, thus you can do it yourself next time.

Fortran count intrinsic leading to segfault

I am experiencing some unexpected segfault after introducing a cleaner code making use of the count intrinsic. The code I had was
n = 0
do ico = 1,cpatch%ncohorts
if (is_tropical(cpatch%pft(ico))) then
n = n + 1
end if
end do
where cpatch%pft is an array which by definition has length cpatch%ncohorts.
I substituted it with
n = count(is_tropical(cpatch%pft))
Also is_tropical is an logical array of size 17 defined as
is_tropical(1:13) = .false.
is_tropical(14:17) = .true.
Is there a situation where these two portions of code would not perform the same set of operations?

Is AutoHotkey capable of defining Arrays in a zero based order?

I've often been frustrated by the fact that AutoHotkey is not a zero based language. It doesn't match well when you are translating code from other languages, or even interacting with them such as in JScript through COM ScriptControl. Even parsing DOM elements you have to account for them being zero based, it just seems that most languages have adopted zero based arrays.
Now you can declare an array and make it zero based by doing this:
arr := []
arr[0] := 1
The above works, if I asked for arr[0] it would return 1. But if I use length() method it returns 0, even though there is a value in there!
If we declare and then push():
arr := []
arr.push(3)
It's always stored starting from 1, I want this changed!
Is this possible to do?
Because AutoHotkey is a prototype OOP language (like JavaScript) you can override any function, even built in ones. Below is demonstration of overriding Array(), which according to Lexikos is an undocumented fact that it overrides defining an array as such [].
I didn't believe it possible as there are several threads on the forums asking for zero based to implemented natively, but none offered a solution. Even the thread where an override of Array() was demonstrated made no mention that this would be possible!
As a bonus, I included split() (zero based StrSplit() function), to help demonstrate further the endless possibilities of this feature.
Just to note, I haven't unit tested or implemented ever method override, it's possible I've overlooked something but I felt it was enough for a proof of concept. Further, I have no doubts that this will affect performance on large arrays, particularly because of how I implemented Length() for this demo.
x := [] ; declare empty array
x.push("Zero Based rocks!") ; push message to the array.
msgbox % x[0]
x := "" ; clear our Object
x := split("AutoHotkey with Zero Based Arrays")
msgbox % x.2 " " x.3 " " x.4 " " x.1 " " x.0
Array(prm*) {
x := {}
loop % prm.length()
x[A_Index -1] := prm[A_Index]
x.base := _Array
return x
}
split(x, dlm:="", opt:="") {
r := []
for k,v in StrSplit(x, dlm, opt)
r.push(v)
return r
}
Class _Array {
; Modified .length() to account for 0 index
length() {
c:=0
for k in this
c++
return c
}
; Modified .push() to start at 0
push(x) {
if (this.0 == "" && this.length() == 0)
return this.0 := x
else
return this[this.MaxIndex()+1] := x
}
}

Resources