hello everyone and welcome to yet
another Recreation programming session
with Mr Zin have you ever generated an
SSH key for GitHub for instance or
something like that uh have you noticed
that when you generate like a random RSA
SSH key it always prints this weird
thing uh which is called random art
right so what the hell is that right so
someday I just like look at that and I
just like thought to myself what the
is this and I started to
Google Googling it and I found this
specific um you know super user page
right so stack exchange page right and
the explanation is actually kind of cool
so Random art is meant to be an easy way
for humans to validate keys right so
usually keys they have fingerprint uh
which is a short sort of like a short
summary of the key uh right and if the
Fingerprints of the keys is match that
means the key is match right but uh
comparing them one by one is actually
error prone for humans for human
perception uh right so and maybe you can
miss something maybe the begin and end
the heads and tails uh match but the
middle doesn't match and this is
something that people usually do right
so when people look at the huge strings
of hash functions or fingerprints and
stuff like that they don't usually
compare the entirety of the thing they
usually compare heads and tails and as
far as now there is even an attack that
is designed to exploore that specific
behavior of humans by the way right I
think I heard something like that uh
right so what was proposed instead some
time ago in
1999 is to actually visualize the hashes
with images right so because images are
easier for humans to P perceptually
compare right and this is what those
images are so it's a simple algorithm
relatively simple algorithm that takes
the sequence of bites and turns it into
an image that uniquely identifies that
sequence of bites so then if you compare
fingerprints you don't compare the
specific things you just like visually
match the pns right Which is less error
prone specifically for humans so which
is rather interesting so I just
bookmarked this entire page to look into
that later maybe it's a potentially
interesting uh topic for streaming and
uh there is a um
basically um a link to a paper in here
that explains how all of that is done
it's a very interesting paper uh I
wonder if I can actually
invert um the
um how is it called the callers so I do
have dark reader and it is on but it
doesn't work on PDF okay so that's fair
uh that's actually fair so um did I
already so validate here it this I want
to open it in new PDF there we go so and
that means I can probably just zoom in
so hash visualization a new technique to
improve real world security and it is
actually kind of fascinating the way
they generate images right so they
generate images by creating a a
visualization function uh right so
Random art a possible solution random
art is apparently some sort of algorithm
that was described uh some time ago uh
there is a link to a website but that
website is kind of dead already right I
looked into that uh L and it's basically
dead but the idea is to create a
function right so it's to create a
function with two arguments uh with the
values from minus one to one right so
essentially Square means that there is
two of them meaning that they're all the
possible pairs of of values from minus
one to one that's what it means that's
what mathematicians usually mean when
they have a function and the function
has a timee type of pair of values from
minus1 to one so it's sort of like a
description of a type right that's
basically what they mean with the arrow
they say this value maps to a triple so
the three uh integer three vales three
numbers from minus one to one so and
what this function actually Maps it Maps
coordinates over an image X and Y and
since they're from minus one to one
they're normalized right like an open
Jael and and stuff like that and they
map it to three values and those values
are RGB values so I'm not really sure
why they mapping it from minus one to
one but I suppose minus one is means
like zero intensity and one means the
maximum intensity we can use this
specific mapping of the RGB but we'll
have to remap it to 0 to one or to 0 to
155 anyway so but whatever so
essentially how do you um create an
image out of the sequence of bytes right
they map a sequence of bite they
associate a specific sequence of bite to
a random function right so they generate
a random function like that so they
provide an example of a function that
generates an image uh right so and the
function very simple right it generates
like a gray gradient all right so
there's somewhere I think an example uh
that demonstrate yes so there we go here
is the uh gray gradient of this entire
thing um right and there's more
complicated functions that map XY into
RGB and stuff like that but how do you
generate a random
function so what they do is actually
fascinating right so the
function f can also be seen as an
expression
tree which is generating using a grammar
G in the depth parameter D think about
it for a second they these
are generating as of a function that
renders an
image this is what they
propose this is so cool I want
to implement that and that's why I
decided to stream today like holy
that's so cool right so you take
like random grammar uh and generate an
as abstract syntax tree you literally
generate like a programming language
code in a programming language and then
you interpret that code in a programming
language generating a
image so that that's basically what they
proposed to do and how do you map a
sequence of bites of fingerprint to a
specific you know as they just use that
specific sequence of bytes as a seed of
a random number
generator that that's what they do right
so uh and for instance um there is a
simple grammar in here right in BNF uh I
think I think I did a Walky
somewhere uh this is a not particularly
convenient PDF reader but it is what it
is yeah there we go so here
is uhuh here is grammar right so here
you have the root expression which is
three C's I suppose RGB and three C's
can be either a or C+ C right c plus c
so add C and C
C and multiply and a is either a random
number from minus1 to 1 or the X the
first argument of the function or a y
the second argument of the function and
these uh basically fractions that you
can see in here these fractions are the
probabilities when you are iterating
through this entire Gramma these are the
probabilities that that particular
branch of the grammar is going to be
picked when you generate the function so
they also have this very interesting
diagram so this is basically an IST of
one of the function they generated right
it's it's kind of small but you can
clearly see that for instance they're
using uh signs in here so there's a
signs there's modes there's mix which
blends the colors and stuff like that um
right so they actually said a very funny
thing that the actual grammar that they
used for testing in this paper is too
big to put in the
paper and the only thing they managed to
put into the paper is is this lame as
grammar um right so that means if we're
going to be coming up with our own
grammar right we have to be creative and
stuff like that um so what's funny is
that is that I already kind of
implemented a similar idea before uh
perhaps one to one is behave easier with
s and cos that's a good point actually
that is probably why they output minus
one and one because then you can do
different interesting things and for
instance here is like a pretty cool
image that they managed to generate
right so and you can obviously see the
periodic things right signs and cosiness
and stuff like that right uh so some of
them are grayscale but I suppose like I
don't see why it could not be color
right some of them I think color uh
right for instance this is what they
manage to generate so and I suppose the
way you then generate uh these kind of
images is basically uh sampling uh that
function at a at a smaller resolution
right so that's basically what you're do
you're just sampling it at smaller
resolution because um the function is
continuous right X and Y are continuous
from minus one to one right so that
means you can scale it to any resolution
you want right so here is a very small
resolution uh right so we can make it
like super big um right and honestly I'm
not really interested in generating this
kind of image images right so I'm not
really interested in that I'm interested
in generated something like this at
bigger resolution uh I think it's going
to be rather interesting and speaking of
like I already said that I already kind
of implemented this kind of thing before
and I implemented this kind of thing in
a form of fuzzer right so I created some
time ago a thing called BN BN fuzer
right so uh let's take a look at it I'm
going to put that in the chat and for
people who's interested it's going to be
in the
description I think Boomer doesn't work
as expected Boomer is BR broken again is
Boomer broken again uh I really
apologize for
that um I really apologize if the Boomer
is broken again but was it at least
clear what I was talking about um so I
don't know was it like a black screen or
was it just staring a bit uh I don't
know so kind of clear okay so that's the
most important thing it doesn't really
matter if it was working not properly
what's important is that whether it's
clear what I was talking about uh there
was no Zoom oh okay fine
um all right that's cool uh so I
implemented this idea in the form of BNF
fuzzer right essentially uh what you can
do with this specific thing is you can
create a BNF grammars right so you can
create a BNF grammars and then generate
a shet ton of random uh text based on
that right so and I don't remember what
I implemented it for I think oh yeah I
wanted to actually fuzz my IRC
implementation right so IRC has a
specific format and um I think I just
implemented I literally took uh IRC
format a BNF of IRC format from the RFC
right and I just put it in here and I
implemented a parer and interpreter of
this file to Generate random messages
that uh
confront to to this format right I I
hope I pronounced that word correctly
but that's besides the point uh so I
already implemented something like that
but I wasn't generating really trees
right I was generating text uh yeah the
postal codes and stuff like that so
there is a format to generate different
postal codes uh right so there we go so
you can actually uh generate a lot of
postal things um so it's basically like
that but for generating ests of
functions that you then later in
interpret as as a program right so you
write an interpreter for the program you
generated and that program actually
renders an
image how cool is that I think
that's so freaking cool I really like
this idea uh so uh we can take a look at
at this specific BNF fer right so let me
actually maybe clone it I I don't think
I have it cloned anywhere so uh so let's
go to soding I think it's actually not
part of soding I literally implemented
it for myself self let's do clone and
let's clone it uh do I have go right so
here is go uhhuh so let me see so I can
do something like go build go build
yourself and there we go we've got a BNF
executable right so that's why uh go is
such a great language because you can
just download the source of code of go
and just build it without
downloading dependencies or some other
without convoluted build system or
anything you just take the source code
and make a executable out of
that right so that's how software
development should be just saying okay
so anyway if we try to run this entire
thing all right so it explains how we
supposed to use that right so it's
supposed to provide a file uh BNF file
right so one of the BNF files we have is
a postal codes uh right so it's this one
do I have a BNF mode I have a no I don't
have it but anyway we're not going to
have highlighting it here so let's
provide a file uh example postal right
so and it also wants to have an entry oh
this one is interesting so entry is a
symbol name to start generating from
passing exclamation mark as the start
symbol name lists all of the available
symbols in the files oh that's actually
very interesting holy this program
is self-descriptive who wrote that
program did I actually wrote that
program like the program actually
explains to me how to use it
what the
did they actually follow all of my
advises on how to design programs like
what I wrote this program like long time
ago honestly like how uh two two years
ago honestly but I updated it last year
or something like yeah okay
so it's a pretty convenient to use if I
do say so myself uh so there we go so we
have different uh things you can
generate right so postal address I
suppose we want to generate a postal
address
uh right we generated a random postal
address based on a grammar in that
specific file right we can generate more
or another one or another one we can
generate as many as we want honestly
right so and as far as I know uh you can
actually specify how many of them you
can generate okay so there's a count you
can say Okay generate like 10 of them
for me uh right there go so we generated
like a temp postal address right and all
of that is based on the BNF group
grammar so what we're doing in that
specific paper we're doing a very much
similar thing but for the functions that
generate images all right so and
obviously like it they also mention a
specific depth because the grammar is
recursive right so it self refers so you
can actually go indefinitely sometimes
right so because of that they have a
specific depth uh and stuff like that
and what's interesting is that what's
interesting is that
uh doesn't the definition of the
function uh like this remind you
something right so it's a function that
takes X and Y and outputs a triple RGB
doesn't it remind you
something chat chat chat doesn't it
remind you something that we did before
we actually some time ago implemented a
neural
network that had two inputs X and Y over
image normalized from 0 to one and
outputs RGB and we trained the neural
network to reproduce
images we actually and what's funny is
that neural networks are function
interpolators Universal function
interpolators so we already kind of did
that idea but with neural network
here instead of like using neural
networks we just use mathematical
Expressions
directly but to be fair neural network
is just like a shut tone of mathematical
Expressions anyway
right it's it's kind of like it's it's
kind of similar right
so hm that's actually pretty cool I
wonder if you can use a similar
idea all right uh of random art and
associating fingerprint with an image
but instead of generating random
Expressions you Generate random weights
over a neural
network okay we thought about
that that's actually kind of cool right
so yeah instead of generating a and
stuff like that you just like Generate
random weights uh but maybe it's not
going to produce anything particularly
nice looking or recognizable for humans
or anything like that uh so yeah uh and
for anyone who's interested what I'm
talking about like uh I'm going to leave
the link to the you know
NN H playlist right so where we were
developing this specific idea and the
source code for that specific idea
should be available in soing SL nn. on
GitHub right so there's some thing yeah
there we go so that's literally that
honestly that's literally that but for
grayscale image right so here is the
neural netw
where you have x y and also a random
parameter right so it's more of an
interpolator and the output is an
intensity of the pixel right so and we
trained it to reproduce either left
image or right image all right so and we
identified uh left image and right image
by this neuron being either zero or one
but since it's continuous you have an
opportunity to actually then use that
neuron to interpolate from one image to
another one right it's it's kind of a
similar idea uh right so but instead of
neural network we use function but
neural network is function anyway so
right it's all of that all of that is
connected all of that is
connected uh training in on random art
to crack
the that would be an interesting idea
actually right so
damn huh but I mean you won't really
crack the hash you will just restore the
fingerprint which is not that big of a
secret usually anyway so
yeah that's pretty cool that's pretty
cool that's pretty cool okay so we got
some subs that I would like to
acknowledge actually uh so where do I
even start so winter core thank you so
much aqu here thank you so much quis
love zore thank you so much for one the
message two years of Epic penger Club
where does the time go I don't even know
I don't even know so Oliver Vick thank
you so much for tier one Lis thank you
so much for twitch Prime with the
message sub because of soup I suggest
trying pasta with strawberries yeah I
heard about this one right so poles have
this very fascinating dish where they
eat um um pasta with strawberries right
at first it may sound like crazy but
then if you remember that pasta is
literally just a boiled bread and in
fact it is very much neutral in that
regard right so because we eat uh toast
with Gem and toast is is bread right so
if toast with Jam is fine why pasta with
strawberries would not be fine it's it's
also bread with strawberries right so we
already eat that in form of a toast and
and jam so I I'm down to try that right
I don't to try that unfortunately like I
keep forgetting every time to try it
though I do have pasta I do not have
strawberries so I probably need to buy
some strawberries thank you for
reminding me about that so PA Theory
thank you so much for1 with the message
paper stream happy Sunday Monday happy
Sunday Monday to you too confused and
more confused thank you so much for
tr1 hope I pronounced your correctly
thank you so much for one and last that
thank you so much for twitch Prime and
thank you so much Rodrigo called deara
Lima all right so let's go and
try to implement something right so
let's go into the zoin and I'm going to
create random art uh right
and I suppose we're going to start with
just downloading
no. right so we're using C today we're
using C so I think I'm going to start
with just implementing the engine that
given a function right which Maps uh X
and Y to RGB just generates an image at
a given resolution right that's the
thing I want to do uh once we Implement
that engine we can implement the as
generator maybe a interpreter then we
can Implement as generator so that's
roughly the plan that I have in my head
right um so let's actually grab N.H and
by the way for those who doesn't know
kn. finally released right so for a long
time I actually kept kn. in visualizer
finally I decided to actually release it
uh in a centralized repost so if you
have any suggestions any P requests or
anything like that uh submit them there
I actually very actively look into the
pull requests in here right unlike in my
other projects um right so let's
actually grab no.
h j compiled random art one this is such
a cool idea holy
usan oh my God you're getting VIP for
that one uh I don't know I really I want
to Implement that I want to
implement like a jit compiler for random
art you know what I'm talking about like
a thing that literally generates
assembly at the run time and ho if I
want to do that
bro but I'm not sure if we will have
time to do that right it like basically
the idea that we use in BNF jits you
know what I'm talking about right so
some time ago uh we did this BNF jit
development and uh where is the BF not
BNF BF J I'm sorry right so this is
where we would load the code in brain
we would analyze it and then
compile it down to literal x86 64
assembly at run time and then jump into
that assembly and execute it right so
it's not really jit in in it's more like
ahead of time compiler but I
mean also you can say it's a just in
time compiler it's just like depends on
definition but yeah so we could use the
same technique to then uh compile the
random art to uh to to assembly at one
time I don't know why but that that
sounds kind of cool right isn't it right
this like another cool crossover of
different projects and and stuff like
that I really like that uh right so also
to do uh BF jit uh video for anyone
who's interested um so okay so let's uh
download uh no. where is the row
file uhhuh so I'm just going to download
this entire thing let's go so
what we're going to be using um maybe
we're going to be using stb image right.
H to you know generate the images sounds
good I suppose uh random art. C right so
let's just create this as a hello
world
right um so print F
hello world that we go so and we need to
create a build system in here right
we're going to be including Noob and
since Noob is a header only library
right so we do Noob implementation
uh right so it also includes knob as a
header and as a C file so in here we're
going to be accepting the arguments
arguments are very important because
we're passing them into Noob go rebuild
yourself uh rebuild yourself uh right
and this specific macro extracts the
information about the current source
code and the current binary from the uh
arguments in here and then makes a
decision whether to rebuild the build
script or not uh right so Implement yeah
thank you so much
Implement uh there we go so and in here
we just need to create Noob CMD by the
way recently in Noob I added a very cool
feature which is stripping the prefix
right so let me show you as you can see
uh no functions right no uh has a lot of
prefixes right and the reason why all of
the names in a no Library have pref is
because we're trying not to repeat the
ray Libs mistake the rbs1 billion
mistake of not having any name spacing
or any prefixing and because of that
colliding a lot with um you know names
for windows. which makes it very
difficult to use on Windows right it's a
huge pain in the ass and everyone who
tried to develop uh with radi on Windows
knows that like it's insanely painful to
the point that you have to sort of like
isolate a lot of names into separate
translation units uh right and then link
it separate it's it's a freaking mess
I'm telling you it's a freaking mess I
I'm telling you this is a billion dollar
Mistake by rayan unfortunately I really
respect rayan as a software developer
but that's a huge mistake that's a huge
mistake on the other hand I do
understand that this is
annoying it is annoying right so it's
just like like why it it artificially
inflates the names of the function where
they could be like very simple and very
concise and like you know nice what I
came up with I came up with a
revolutionary technology of the prefix
stripping so Noob introduces a macro
called strip prefix and look what this
does uh if you enable this macro each an
individual name has an alas without the
prefix so this is needed in cases that
you know for sure that none of the
unprefixed names of no uh collide with
anything so we can just strip all all of
the prefixes and use it without any
prefixes right it's almost like
doing um using name space Noob but
without using Shady language not going
to call the name of that language right
so it's like imagine using actually good
language but that good language also has
like using name space or something like
that you know what I'm talking about
it's almost like that um
right so and what's funny is that if one
of the names for instance collide with
something right not all of them but one
specific name you can always after
including this entire thing just unep
that specific name
right you can just like you strip
everything right so you say uh strip
prefix right and then one specific name
kind of annoys you you can undefine that
thing and that's going to be with
prefix can your C++ do that I don't
think
so I know it's stupid right so actually
C is a pretty shitty language and the
reason why we do all of that stuff is
because we trying to work around this
shittiness but it kind of works right so
it kind of works so we're trying to have
like The Best of Both
Worlds uh right so basically name
spacing with prefixing but also at the
same time not having to write those
prefixes uh right so I think I think
that's fair and because of that I can
just use uh CMD right I can just use CMD
I think go rebuild yourself doesn't have
a prefix stripping um I think it doesn't
have a prefix tripping because it is red
definable things that red definable they
are not uh stripping the prefixes yeah I
I don't remember the specific but uh
anyway whatever so here's the CMD and
what we're going to be doing in here is
the CMD append uh so we're going to be
appending some stuff in here so it's
going to be CC we're going to enable a
bunch of uh warnings in here so w all W
extra uh all right so maybe we're going
to also enable the debug information uh
ggtp right so I'm going to be outputting
random art and we're going to be be
compiling random art. C there we go and
then what we're going to be doing we're
going to be just running run this thing
synchronously right run this thing
synchronously and usually this thing
returns you uh false in case of an error
in that case you just return minus one
all right so let's try to compile this
entire thing and see if we didn't make
any mistakes no. C and there's some
mistakes in here so what you don't like
what should don't oh because you have to
pass it by value yeah I don't remember
so now since we Bo strap this entire
thing we can run it and we do have a
random art and run random art it says
hello world that seems to be working uh
okay
[Music]
good okay so now we need to download the
stb image right so nothing's um
stb hello artist hello atist
oh I'm a professional atist
I Supply a local village with SH ton of
me
methane I'm so sorry uh
um anyways so let's download this
thing uh budget yeah budget math lab um
all right so this is stb image and let's
actually include this entire thing in
here right so stb image. H uh stb image
uh so stb image implementation right
Define uh there go let's try to rebuild
this entire thing so yeah now we have to
link this entire thing with math
Library uh all right so otherwise it's
not going to work so the cool thing
about Noob I only modifi the noob and
Noob automatically rebuild itself right
because there's new version of No and
then run itself and then build this
entire thing so it's always at almost as
convenient as using a scripting language
but instead you're using real statically
typed compiled language but with the
convenience of the toy scrip in language
you know what I'm talking about know
what I'm talking about shoes
for
um oh God damn it bre can use
local farst pollutes the town with
methane
L okay
anyways
um let's continue so we have this kind
of thing uh how are we going to be
generating all of that stuff all of that
stuff so maybe one of the things we we
can do we can
simply I don't know we need a canvas
where we're going to be generating all
of that stuff right so uh let's define
width right so and width is going to be
maybe 400 and height is going to be 400
right so something like that so I want
it to be square because the X and Y are
kind of normalized right so uh maybe
this is too much maybe this is too many
samples but we'll see we'll see uh right
and here we can do something like uh
pixels right so this is going to be
width multiplied by height so that's how
many pixels and obviously this thing is
going to be
static um so another thing we want to do
we want to basically render right and
here we're going to be accepting the
function um so since the function
accepts pairs of the numbers and returns
triples maybe we need to introduce
things like I don't know Vector 2 and
Vector 3 uh right Vector 2 which is
going to be float X and Y and Vector 3
uh which is going to be XY
Z right something like that and here
we're going to be accepting the function
uh which returns Vector 3 right and
accepts Vector 2 right so this is
basically we say that we're accepting
pointer to the function that does that
um right something like that something
like that and this thing is going to be
uh rendering the pixels so maybe it
makes sense to actually literally call
it render the pixels so and maybe we're
going to have like different functions
that we sort of plug into these things
like render pixel
uh right so and we render like a gray
gradient right so and a gray gradient is
going to be this
function which
basically yeah which basically returns
like a triple axis right so we can say
it's going to be Vector 3 so we're using
a little bit of a cliteral pattern in
here right so this is a cal p and this
is going to be X this is going to be Y
and this is going to be Z right so we're
taking x coordinate right so this is the
x coordinate and we're just like using
that as an intensity for both RG and B
um to be fair we're only going to be
using Vector three as the caller right
so maybe because of that I want to
convert Vector 3 to color I think that
makes more sense uh all right so that
enables me to use RG andb uh in here and
this becomes RG andb I think that's much
better so maybe we can even get rid of
that and just like do it like that so
it's a little bit closer to how it is
defined within the paper itself right
you see within the paper that specific F
I'm s I'm sorry if the Boomer doesn't
show it right so but this is how it's
defined within the paper right so I know
that the Boomer is kind of broken right
now but whatever so uh yeah and
essentially these functions are going to
be pluggable in here right so we're just
plugging them in uh right and this
engine is going to be rendering those
functions into the final images and
stuff like that so that's basically the
idea in here okay good uh so how we're
going to be rendering all of that stuff
so we need to reiterate all of the
pixels essentially right so let's go
ahead and do that so it's going to be x
uh starting from zero and X lets than
width but to be fair I would like to
First maybe iterate the rows usually it
makes more sense right so first we
iterate in the rows and within the row
we iterate in the columns that right
that's the usual thing in here uh that's
the usual thing in here so and in here
what we need to do we need to map the
values of X and Y right remember the
values of X and Y for function they
expect them to be from minus1 to
one but in our case we have values from
zero to widths and will is from zero to
height we need to normalize them somehow
right so we need to bring them to the
range minus one to one uh so that's a
very interesting question how we're
going to be doing all
that so we can bring all of that stuff
to AR range
from 0 to one by basically dividing by
width right so that's one of the things
we can do uh right so let's actually
introduce that as N Y which means
normalized right and we can take y
probably convert it to FL flat right so
all of the operations are in float and
divided by height and that actually Maps
it to a value from 0 to 1
okay after that we can actually multiply
this entire thing by two right
multiplying it by two and that brings
the entire range to a range to zero to
two and after that we can subtract one
from this entire thing and that brings
the range finally to minus one to one
basically right isn't it
sort of like that but not really because
um when we're iterating this enti thing
so this one is more like height right so
this is what we're operating when we're
iterating height is not really included
so this is more like less less and also
less it never really reaches the one so
like that part is kind of included so in
that case somebody suggest to do width
minus one uh maybe maybe we should do
withd minus one but doesn't really
matter in the grand scheme of things
right because our goal is to just
generate some images uh so and it's just
like one row and column of pixels so who
who cares right um so I I guess maybe it
doesn't matter right so that's what I'm
trying to say maybe it doesn't really
matter uh and what we need to do we need
to do the same thing for X right so this
going to be x uh this is going to be
width and that's kind of a Sim similar
idea there we go we have n uh like n x
and N Y which are normalized which you
can then pass to F right honestly it
would be easier to actually pass it like
that uh
where yeah where that would be like a
separate arguments like this X and Y
maybe because of that we don't really
need Vector 2 but maybe we will need it
in the
future who knows
maybe we will need it in the future but
as of right now it just like makes it
easier to do like this right and that
gives us the color right and we have
color r g and B but the problem with
those things is that they're value from
minus one to 1 and we need them to bring
to the values to 0 to 155 right that's
what we need to do well we can do a
similar process we did for NX and n y
and basically
maybe uh add one right so that
effectively brings that range to 0 to
two then we can divide this entire thing
by two that brings the range to a value
from 0 to one and then we multiply this
entire thing to 255 which finally brings
this entire range to 0 to5 and that
range actually includes minus one and
one right so it's kind of
there's a little bit of discrepancy
right so this range doesn't include the
last value this one probably will
include it but again in a grand scheme
of things who cares right am I right who
cares so it's just like a little bit of
weirdness on the edges and just like
whatever right so the resolution here is
400 by 400 whatever um right so we want
to kind of repeat this entire idea for
for the rest of the components isn't
that more part of the gray gradient
function or is this algor M of the paper
uh the um right now this function as you
can see is hardcoded right what I'm
doing is I'm just implementing the
general engine that given a function
that Maps two floats to three floats
generates an image right as you can see
this function is pluggable right so the
goal right now is to implement the
rendering engine that just renders the
pixels and save them generating random
functions making this thing random is a
separate problem
uh oh you're talking about something
else I mean color is generally expected
to be 01 true but we're going to be
saving that color using stbi and the
library that we're using to save in
images expects the pixels to be from 0
to
25 right so I agree that generally it is
like you know like that but uh once we
receive the value from the function we
have to comply with the interface of of
the library and all that in uh the
interface comes from the format that
we're using we're going to be saving it
into PNG into the PNG we're saving in as
RGB 32 and that's what we have to do uh
right so it's like this is not our
decision this is like dictated by the
libraries that we use that's why it is
important to control your third party
dependencies by the way but I mean you
won't be able to escape that even if you
write your own library because you're
limited by the formats that you use
right and formats usually like expect
you to be the values from 0 to 155
anyways uh so let's go ahead and just do
the same thing for all of them uh all
right so for literally all of
them plus one 2 255 and uh I suppose
we're going to right away just assign
them to a
bite right so it's going to be r g and B
uh so this one is G this one is B so now
one individual pixel in here is actually
U
in32 which means means that um we have
to pack it somehow we could have create
made it a structure right we could have
made it a
structure but I don't know
right will be kind of cool to to have it
as a structure so
essentially uh T Dev struct uh rgba 32 u
in 8
TR uh G b b a right and we can say that
pixels is R GBA 32 the size of the
structure is going to be exactly the
size of U inside so we don't have to
worry about that and because of that
because of that we can just do something
like pixels uh right so we need to maybe
identify its index which is going to be
y the row multipli by the size of the
row which is width plus x uh like this
and here we just put dots right so we
assigning this stuff directly and then
Alpha is going to be 255 so that's what
we're doing in here uh that's how we are
approaching this entire
stuff so it's crazy how chill the chat
is when it's sub only yes that's
literally the point that's literally the
point right so and I recently switched
to sub only because people quite often
disrespect the process of software
development right because the thing that
I doing here is very complicated and
it's very much mentally taxing right
doing programming by itself is already
difficult I also have to explain what I
do I also have to try to make it
entertaining I also have to read the
chat and I also have to moderate the
chat that is insanely difficult and what
I noticed recently as we have more and
more people in the chat is that a lot of
people come in and complete completely
disrespect the thing I do completely
disrespect the difficulty of the thing I
do and the process so by putting the sub
mode on uh I hope to only uh leave the
people who do respect what they do right
so I don't really ask too much right so
I don't really ask too much I just ask
ask to respect the process in here right
and do not distract me and do not try to
troll me or anything like
that so that's the only thing I ask
it is what it is and it isn't what it is
when we used to be a smaller Community
it was kind of okay but as we grow and
grow we having a little bit of a growth
pain right so but we're slowly adapting
we're slowly adapting so maybe we will
get there cheers by the
way and I do apologize to people who do
respect what I do but can't pay for the
subs and stuff like that uh all
everything I do is going to be free
right so it's not like I'm going to put
a subon stream right it's only subon
chat so the stream is always going to be
free and available for everybody and all
the streams are going to be on YouTube
right so you can always watch that you
don't have to pay to watch my
streams
cheers so anyways so we got this thing
and this entire thing generates the
pixels right so we generating the pixels
and after we generated the pixels out of
the function uh I suppose we want to
save them right so we want to save them
so stbi images um
stb uh I think oh I just realized that
I'm using the wrong library right this
library is
for reading images what we need
is um what we need is the library that
writes the images so bias we all agree
it's a good thing yeah because everyone
who disagreed actually left the stream
that's understandable but maybe that's
exactly what I want I Eco Chambers Eco
Chambers uh people condemn Eco Chambers
on the internet but to be fair um I
think in the modern internet the modern
internet became so goddamn noisy
you actually have to create this
isolated environments to protect
yourself from the outside noise right so
I I think the future decades on the
internet are going to be the Decades of
e Chambers right because how goddamn
noisy the internet has
become um right so everyone is going to
be creating their own sort of like
isolated spaces where the internet
cannot come in
um so I mean to some extent even frame
circles are Eco Chambers and that's not
bad in itself yeah I don't really know
why it is condemned so much right so why
is that a sign of being close-minded no
no no no it's just like um I think it's
a sign of informational hygiene that's
what it is right it's not a sign of
being close-minded it's an informational
hygiene that's what it
is e chamers as good as the people in it
yeah and as far as I know wasn't the
theory of Eco Chambers like debunked
recently that on the internet there's
not that many Eco Chambers anyway uh
right because they right so the internet
like at least the social platforms they
live of of the engagement and the way
you form engagement is by creating the
filter Bubbles and then smashing them
together right and because of how social
media algorithms works all of the
potential Eco Chambers gets burst all
the time because that creates a lot of
energy that creates a lot of engagement
right
what's interesting is that on how on the
modern social medias social media
networks Eco Chambers are constantly
created and destroyed for the sake of
creating engagement so yeah that's
everything I want to
say um so what do we have in here so we
generated the pixels we need to write
the pixels into the hard drive right so
to write them we need a different
Library which is stb image right not stb
image stb image loads the images
um
so stb image
right uh row and let's just like open
this thing in here uh double get and uh
let's actually download this
thing uhhuh and I'm going to just put
this stuff in here so because of that we
don't really need to load the images at
least yet
uh right so we are going to do stb image
right
implementation uh stb image right
stbi WR PNG so this is what we're going
to be writing in here
cool so uh here is the output output PNG
so width and height if I understand
correctly is in pixels so this is going
to be width and height the amount of
components is basically the size of the
pixel right so we have four components
in here uh here is the pointer to the
pixel and then we have to specify the
stride which which is basically the size
of the row but not in pixels but in
bytes right so in the size of the row in
pixels is width and we know that there
is four bytes in here so multiply by the
size of uh you can't see this okay
rgba 32 cool um so maybe we can even
Factor it out output path right so con
Char output path like so so and then I
don't remember so what does it return in
case of an error um
so what does it return in case of an
error as suppose the
same
return uh each function return zero on
failure and non zero on success okay so
that means if not uh right we have to
report an error so maybe we can use log
no blog error um could not save the
image s which is output path and we just
return one there we go okay so let's do
no what we have in here so you in we
need to do STD int uhuh so compilation
uh okay so we're using yeah it's kind of
interesting so I really like to use no
not only for building but also in the
main application that I'm building with
Noob so let's quickly do that because no
is actually generally useful Library
surprisingly and I can also strip the
prefixes here as well because why not
all right so and then I do random art
and it generated random art which is a
gray scale right so we just like Rand
literally rented that function uh that
they supplied as an example so here it
is so here's the function though
it's kind of a weird
function
uh why is it to invert it in their case
are
they are they
just it makes sense to for it to be like
that isn't it weird how to me the gray
scale never looks like it's equally
black as
white uh your dark Creer ah oh okay
[Music]
[Laughter]
was so
stupid classic
classic
oh um it's way oh you mean in general
it's way more black than white it
probably has something to do with non
your perception of like a human Vision
or something like that I think that's
what it has to do with uh yeah
g uh all right so we've got these kind
of things so do we have more interesting
functions that we can try right so of uh
if X and Y so which is the
multiplication greater than zero then X
y1 otherwise F mode uh so a more
complicated example is the following
expression which is shown in 2 b
okay so this is oh this is actually kind
of cool we can try to uh to render that
so
let's uh implement it as something like
cool uh and we're going to accept x y
uhhuh and what do we have in here can I
actually split this entire thing and
just have it
uh uhhuh so I just want to have it like
this so this is this is the function
that we're trying to code in here okay
so if x multili y is greater than zero
then we just return um x y and one but
well in fact we want to return something
like this right I wonder if it's going
to work right so which return like that
but anyway otherwise we need to do F
mode
XY then just repeat it three times I
suppose might as well just do something
like this and it's going to be r r r r r
r r r r
r
okay and let's try to reting and it
doesn't work because it wants to
have cliteral it literally wants to have
cliteral uh it's also F mode F I believe
yeah it is do we yeah so it probably
math function is imported from here but
that's fine I wonder if we can just make
this thing to automatically run the
binary um so CMD append run oh here's an
interesting thing yeah so after you run
a command you should not forget to clean
up reset the command right so then you
can reuse that structure again if you
want to so this is such a common pattern
that I created a function called run syn
and reset which accepts CMD by pointer
and it does this step for you out
automatically so you just have one CMD
Dynamic array you populate it with
commands then you run and reset it again
so you can reuse it one more
time right so and you can run it again
so that that's how it
works it's actually rather convenient
honestly all right so I I don't know why
I didn't think about that before but
that's that's literally what you want so
the next step is going to be actually
combining together these two things into
a single expression so I can just like
provide these commands in here run and
reset them automatically but I can't
really do that because CMD append is not
an expression it's a uh it's a statement
because it's a macro right let me
actually show
you uh yeah so it expands to Noob di
append menu right and OB manyu is a
statement so to combine these things
together uh what what I want to do right
so I can do CMD append run sing and
reset right so I can do something like
that it accepts CMD and the rest of the
parameters that you want to append in
there right so and it's very easy for me
probably to do something like CMD append
uh I forward that CMD in there and the
varic parameters VI ARs and then I use
the comma operator to then run and reset
set the very thing that I just populated
right so it makes it super easy to
actually combine uh these two things
together but you can't do that because
same dend is not an expression you can't
really do it like that right um You
can't really do it like that unless I
refactor finally this thing to be an
expression to make this thing an
expression I need to turn it into
function uh right so in GCC you can well
I mean I want it to be cross compilable
okay uh so right so but to be fair so if
it's if it's a GCC exception extension
it will work on clang but it will not
work on msvc and we do support msvc by
the way I'm sorry we do support msvc so
I know it's just it's lame it's
Microsoft it's msvc but we do support it
right so I have some projects that
depend on yeah I I understand like I
really really understand I I have the
same reaction honestly I have the same
reaction but this is the real life it's
just like it's the same with JavaScript
right I don't like JavaScript either
like seriously I don't like it either
but it's everywhere it's just
like you have to know it you have to use
it it's the same
with uh nishe compiler for compiling
video game
exactly it's a n compiler for compiling
video
games uh so I use the G extension once
into impl lab this in PC they work
better than expected msvc is it's
actually kind of cool MC deated Windows
people installed Linux onto their OS is
it PR deprecated I think mustc there is
a lot of software that still depends on
MVC stuff because MVC has its own
extensions um the way um oh it's a joke
okay okay W yeah yeah so you're joking
about WL um I I heard in interesting
take that I really liked about CN C++ is
that what the standardization committee
should do instead of doing like weird
ass they should just look at
extensions that the compiler vendors
Implement and basically the common
extensions just make them
standard right and like don't do
anything else don't try to invent
anything don't try to like just look at
extensions the compiler developers know
better because they actually develop the
compilers and actually use use them
unlike some of the committee members
right so it's better to listen to people
who actually do programming and do use
compilers every freaking day
right
uh so they are there because they're
useful exactly exactly people don't add
extensions for no reason right they add
them because they need them um they kind
of do it a little bit Yeah I think they
should just fully switch to that mode
just don't do anything just like
standardized extension that's it um I
think it I think emac development kind
of got to that point didn't it right so
majority of the time what emac
developers do is just like look at the
popular packages and just like add them
to the emac every release like what's
the common package that people use okay
let's just ship emx with that now uh so
well I mean they they also do a lot of
like a core development right so but
besides the point
in my opinion stand committies can be
Gatekeepers but I'll keep it civil yeah
understandable understandable
gatekeeping gatekeeping but anyway so we
can't really do that so we'll get that
at some point it's just like I need to
sit down and refactor uh this uh macro
to be an expression right so which works
on all of the compilers right on
majority of them GCC Clank uh msvc
primarily basically GCC and and msvc
right so because there's only two
compilers msvc and GCC and GCC like
compatible compilers right as soon as
you support GC you support clang
automatically as
well uh anyways uh right and eventually
we'll get to that point where we can
just have a single macro right so and
this uh structure is basically used as a
memory holder as a memory arena for the
arguments that you put in
there okay so what I can do in here I
just can run it and automatically
recompile and run the the whole thing
which is kind of cool uh random art uh
so it would be kind of nice to maybe do
log in four and just say uh generated as
output path right generated
as uh all right so it's pretty cool it's
very
commed I like that I really like Noe um
what do we want to do we want to
implement cool right so that only
generated gray scale what we want to do
now is we want to generate cool uh let's
go ahead and do that so let's take a
look at
cool there is a little bit of a
weirdness
um in the middle in here that they don't
really
have uh in
there yeah it kind of it's like from the
yeah they don't really have that
weirdness in there probably has
something to do with edges and whatnot
but
whatever uh whatever whatever whatever
um so yeah now we have to implement the
a thingy right so the the main problem
here that we have is that the functions
that we Supply in here they're literally
literal pointers to C
code uh which is not easily
generable uh I think what we have to do
in here is to accept a of the function
and these things should interpret that
as F mod division by zero ah
really uh F
mode what do we do in case of a that's
bizarre bro so it's greater than zero
did
I okay so if it's that's it such a
bizarre thing to do so in case of a zero
what do we
do
um if
zero
maybe just
return uh just add 001 to each
pixel I
mean okay um
just a
second hell yeah thank
you we fixed it fixed
it uh well I suppose maybe you want to
have equals but why didn't they make it
equals here there's no equals in here is
that a type did we found a typ in a
scientific paper in peer reviewed
scientific paper wait a second wait a
second so I'm going to go
back uh right so I'm going to freaking
go back and just run this entire sh and
then I go uh like this there we go
here's the line here's the weird line we
got here's the weird line Amper yeah you
Amper reviewing so then if I put equals
in here and just run it one more
time uh right it's just a we found a
tyer what the
the reproducibility crisis in Academia
is insane I should make a YouTube video
about
that holy Academia is in such a
crisis right we found the typ right so
that's the point of Science by the way
you take a paper you try to
reproduce that should have used Docker
yeah should have used
Docker um okay so that's pretty cool
um yeah so let's go ahead and implement
the grammar but before we do that my
friend before we do that I think we need
to make a small break uh right so
because I need to refill my tea I ran
out of te and will also stream for an
hour so I think the time has
come my
friends all right so uh let's implement
the as interpreted thingy maingi okay so
since we're going to be writing an EST
uh so I think this is going to be like
we need to have a node right so each
node will represent the operation right
so because what we're doing we're
generating this uh you know syntactic
tree right so we're going to be
generating this thing and instead of
calling the function we're going to be
interpreting this as as T right uh so
and each node in here is going to be
like a structure in in our case so
here's the node and the node
it's sort of like a polymorphic thing
right so it needs to have some sort of a
Kind right so we're going to have a node
kind uh and node kind is going to be an
enumeration node
kind so we're going to call it NK and
what kinds of nodes we can have
generally at least for now I suppose
what we want to have right so we only
have two variables right we only have
two variables because of that we can
allocate for each variable its separate
kind right so we can say
nkx right literally and NK y uh and
since we don't really have any more
other variables within the function
right that's enough actually um right so
after that I suppose we can have
something like NK number uh right and
for the number we're going to have a
float number like this right um so when
the kind is going to be X or why the
number is going to be simply ignored
right so again it's sort of like a
tagged Union that's what it is right
it's a tagged Union but in C C doesn't
have tagged Union that's why we
implemented it
ourselves make sense make sense anyways
uh so the other things we have are I
suppose like add and Mt uh things right
so NK add all right so this is going to
be NK add uh and for the NK add I
suppose we're going to have maybe uh
float let's do the following thing uh
maybe we're going to have like a and b
right so if it's a number it is going to
use uh you know a right if it's add it's
going to use both A and B it's a
discriminated Union okay so that that
also makes sense uh so add uh we also
have malt right it's also binary
operator so it's going to be using that
uh do we need anything else I suppose
another thing we want to have is a
triple right so because one of the
values that this function returns is a
triple right so because of that it makes
sense for note to be a triple right or
maybe we have it as a Coler right so
it's going to be color and because of
that we're going to have C well I mean
calling it a callor implies that we have
to call it RGB let's call it a triple
right I think it I think it is better it
will be better to call it triple um so
so far we have notes note kinds that can
encode Expressions generated by this
grammar right which is fine which is
good uh so the question
is how are we're going to be doing all
of that this is by the way incorrect uh
this is not the right way to do that
because when we have nkx
uh we want to have left and right sub
Expressions which are also nodes right
so maybe doing it like that is not a
particularly great idea um so because in
case of if it's add we literally have to
have something like LHS and rhs right so
if it's if it's a add
operation uh so we probably need
to introduce some sort of like a union
yeah we probably need to introduce some
sort of a union C has unions yeah
goddamn come language uh so let's
introduce the
union um so node as so this is sort of
like a pattern that I like to have uh
right so and in here for instance we can
have uh a number um so in essentially
the point is when you have a node right
so you can check if the kind of the node
is NK number and then you can sort of
like interpret the node as a number
right so this is how we usually like to
work with discriminated unions in C
right I have this like a union that is
called as right and it's filled as as
which allows you to sort of convert the
um generic type into more specific one
based on its kind based on its tag right
it's rather convenient right um so and
in here in case of ADD and malt uh I
think we need to introduce something
like a node bin op which stands for
binary
operation usually use anonymous uh stuff
okay that's fair enough right so that's
what I like to do I like to do these
kind of things so uh this is a node Bop
uh and in case of Bop we can have node
LHS right hand side and rhs right hand
side so and in here we have Bob and Bob
can be reused by both add and mold makes
sense so and also we can have a triple
right so node uh triple which is yeah so
uh
first and obviously it is a pointer
second third there we
go uh node triple
triple okay so that's basically the
description that we have uh so if we try
to compile this entire thing obviously
it is not going to compile because note
is not existent right because it's
declared much further we can actually
move it up there right we can move it up
there but we still going to have problem
right because node as is not defined yet
right so node as is defined much later
but if I put nose M add before it's
still not going to work we need to
forward declare uh
node right we need to forward declare so
it's it's one of these old ass languages
right C is very old and it doesn't allow
you to Define types in arbitrary order
like rust or any other modern language
uh right so you have to Define them uh
you know in a specific order so you
can't use the types that were not
defined before because of that the the
way we do that we need to Define note as
the first thing uh and we Define it by
forward declaring it so we just Define
type def first we say that struct node
is actually node but then we're going to
Define struct node much later but since
we at least
declared so other definitions know about
it
right uh other definitions know about it
so and in here we can just do something
like this so that's how we resolve this
kind of problems as you can see it works
it works it works uh so interestingly
how we're going to be actually
allocating this entire right so
when you think about memory management
uh so we viously need to allocate that
somewhere in dynamic memory
right but at the same time uh it's going
to be pain in has to deallocate all of
those
things um so one of the things maybe I
want to
do is to allocate all of that in some
sort of Arena right um some sort of an
arena um
or one of the things I'm thinking about
H um we can have a dynamic array of
nodes Arena time yeah maybe it is Arena
time maybe it is Arena time yeah let's
actually do Arena uh so I think that's
going to be the easiest option in here
uh arena. H so I have Arena
implementation uh it's it's not arena. H
it's just Arena so here it is if anyone
is interested so there's pool request in
there I haven't looked into that um yeah
yeah it's been around for some time I'm
going to let it ferment a little bit
more uh it's not ready yet U and I'm
going to also put this thing in a
descrip so here's the arena uh let's go
ahead and simply download it
row maybe I need to add Arenas to no I'm
kind of thinking that AR like no should
have its own Arenas but I
still um I don't know
I need to find motivation to do a very
difficult executive
decision uh I need to find willpower to
do so um all right so let's include the
arena if we take a look so it's also has
implementation thingy let's define Arena
implementation and let's include arena.
H so the way we create Arena we just
like allocate it statically somewhere
here so it's going to be Arena and let's
call it no Arena uh and let's also zero
initialize it and let's put it static
and there you go that that's it right so
that's how you create an arena and what
you can do now you can actually allocate
things uh Arena a looc right by
providing the pointer to the uh node
Arena right and then you can actually
specify uh how many bites you want to
allocate in there since we're going to
be allocating a single node we taking
the size of the node right and that
gives us the pointer to the node we just
allocated it within the arena and we can
keep allocating the nodes within the
arena and once we're done with them uh
we can do Arena reset which just resets
the entirety of the Arena right so it
just delicates all of the nodes at
once uh that's that's kind of the point
of this enti thing that's kind of the
point um all right that's pretty
poers um and maybe since it's a global
right and it's called node Arena any
node creation is going to happen there
automatically maybe that's one of the
things we can do we can even maybe
create a
function um that just does the following
thing so essentially node number and it
accepts the number right and what this
thing will do it will just allocate a
new node within an arena Arena uh a
loock not assert but a lock uh node
Arena size of node
and that's the node we supposed to
return right that's the node we're
supposed to return here we assign kind
to NK number and then we interpret it as
a number and we assign that number in
there and then we just return there so
we can create these kind of functions
for each individual kind um very easily
and just use it and all of the
allocations going to be localized within
a single Arena that is very easy to
allocate that's essentially the idea in
here at least so uh we also have an k x
and uh y right so I can do something
like node X it's not going to accept
anything but what it does is just this
and then we can have node y y and most
importantly we can now have things like
node add which accepts left hand side
and right hand
side why good question right good
question uh okay so this one is ADD and
now we can just do as um
bop uh left hand side this is left hand
side and the right hand side very easy
now to copy paste this thing and create
malt uh this is malt and and this is Mt
and now we can even create a triple all
right so this is going to be triple um
it's a b c ABC and this one is going to
be triple and
a
b c how about that is that pogers I
think it's pretty po okay so it doesn't
compile so because I did a fory walkie
and potential oopsy dupsy what else uh
wait so this has to be triple by the way
uhhuh so triple oh it's actually called
I forgot that I called them first second
okay first second and
third right so first a
second third uh third let's align
everything properly and can I now use a
little bit of a emx magic
emx
magic emx magic emx magic let's go emx
[Music]
magic okay so it's pretty cool so uh why
I want to do it like that now uh I can
quite easily create these kind of things
uh where is just like node triple right
and in here I can say Okay node X node Y
and node number which is half and there
we go I've got some sort of a node in
here
uh so it's it's very easy to create now
and it's all dynamically allocated in
the arena I don't have to worry about
memory allocation right so it's
localized and now I can very easily also
you know Traverse it interpret it and
stuff like that uh right in this compile
one of the things we probably want to do
by the way is is to implement a dumper
of the uh Expressions right so
essentially it should accept the pointer
to the node and just print it uh so we
can inspect them what exactly generated
I think it's going to be very useful um
all right so what do we have in here so
something like node
print so just use Monet to abstract away
the
allocation yeah that's what we should do
uh all right so then here we can just
switch case upon this mod
right so this going to be kind and let's
take a look at the node kind uh so what
do we have so here they are honestly I
would like to maybe also add a little
bit of flag in here one of the favorite
Flags I have I think it's a switch num
which also checks at compile time that
all of the values of the enumerations
were checked within the switch it's it's
rather convenient right so if I add new
uh enumerations it will fail in here or
at least warn me that I didn't check
some of the cases in here uh okay so
that's basically what we have in here so
maybe I'm going to put this stuff and
also let's create a default case and
default case is going to be
unreachable right so it's unreachable
case and let's put not print unreachable
by the way comes from
Noob so if anyone is interested so here
is the enrichable what it does it just
like prints the message like where that
happened and just aborts the execution
uh so this uh theoretically should never
happen right but it's C so it may
happen because you may accidentally pass
a pointer here pointing at corrupt
memory which may contain invalid switch
case and in a majority of the mod
languages this kind of thing is
automatically generated for you by the
compiler but we talking about C it's a
old ass language it's old last language
okay so in case of X we just print X
nothing nothing special um does
switching I'm I think it does work I
mean the compiler will tell me that I'm
using wrong flag we're going to fix it
when I will try to compile all that okay
so in case of a number so we need to
print that thing so it's going to be
node as number there we go so when we do
add this one is interesting this one is
interesting so we can actually print it
two ways I suppose we can just do node
print um node as LHS
and
rhs right and so the syntax that is used
in this paper by the way they're just
like use a function syntax they don't
use a infix notation maybe this is one
of the things we should do as well right
so let's go ahead and do that so it's
going to print F add like so then
between those things we put this thing
and then we close this entire stuff
right so we're going to follow the
papers
notation uh right so then here we do
malt so this is The
Malt uh and here comes the triple so in
case of the triple oh by the way I'm
doing a walk thing just a second
Point uh so as Bop that's what I want to
do actually so and in here uh we're
going to have a triple and it's a first
second third so and in here we're going
to print it as
such right the second one and this third
one like so all right so that's how
we're going to be dumping all that and
now we can just go ahead and literally
dump um node
print node let's exit somewhere here
with 69 so it doesn't execute the rest
of the code in here we just want to test
how it prints the expressions and it I
think it forgot to put a new line in
here so it doesn't put a new line
automatically print F uh new line um
where am I there we go so this is the
expression that we encoded in here by
the
way so it's it's literally that so we
can go even further uh right so we can
Nest as much Expressions as we want we
can do sum uh node y like so right and
it is it should be automatically
reflected but oh it's add excuse me yeah
there we go so as you can see it's
automatically nested so we can actually
create as many nested sort of
Expressions as possible and there we go
so here's the thing here's the thing
that's pretty cool isn't it I think it's
pretty cool
um so another cool thing is that what we
have to do now is we need to create a
function that accepts the node right so
uh right so we going to call it f it
accepts the sort of like a body of the
function the values of X and Y the
values of X and Y and gives you the
color so what it will do it will
actually evaluate the
function right it will evaluate that
thing for you so it will take this a
Traverse it right so visitor part
sub mode is not yeah it's it's like VM
right it's almost like VM but it's a
it's more like an interpreter right so
we actually basically wrote an
interpreted language right that's what
we did and that's what actually the
creators of the paper did so what they
suggest is just to associate a random
sequence of bytes with an image uh
Implement an interpreter for a language
and generate a random program in that
language and interpret it so that's what
what they suggest that's how they do
that that's random art it's generating
random programs in a madeup language and
then interpreting
them uh so is that kind of cool it's
kind of cool I really like
it um so yeah let's go ahead and maybe
Implement that uh funnily enough when we
going to be rendering the pixels now we
don't even have to really accept a poter
to an actual function we can accept node
now right so we're accepting the node uh
just the node and instead of calling
this function we're going to be
evaluating that function on NX and n
y right so instead of accepting the
pointer we're accepting as and we
passing it to the evaluator that will
evaluate that function for us that's
what we're do now uh right so maybe I'm
going to actually not get rid of that
but I'm going to duplicate it uh so in
here we used to just call this function
like this uh just like this but now
we're evaluating it's not that much
different right so the first version in
here uh calls native code but this one
calls an interpreted
code um so yeah accidentally generating
virus if Jed would be funny it would be
right so if we try to actually generate
like assembly Cod out of that node we
may have a bug that will generate bogus
assembly and it will either crash
everything or create vulnerability or
like a remote execution code or
whatever that would be funny all right
or something that creates a virus that
actually spreads and multiplies but that
the probability of that is very low
anyway so what we have to do uh right so
we have to kind of switch um H this one
is rather interesting right so because
effectively what we have to do
is
evaluating yeah we may have runtime
errors in
here I just realized one of the things
that we may have during evaluation is
runtime errors for instance function
should always return a triple but what
if it doesn't return triple that's a
runtime error that we have to throw
somehow uh so we can add only numbers
but what if we try to add number and
triple we either have to Define that
operation somehow or make it illegal if
we make it illegal that's a runtime
error so
and
yeah we can eliminate runtime errors by
introducing a compilation step that
checks the types
holy yeah
so for example we need to check that
yeah type checking uh so for example
this will type check fine because X is a
variable which is a number right and Y
is also variable which is a number but
what if what if we try to add the triple
end number right so and it's not defined
uh we can actually check that by
analyzing the thing before
executing uh or we can check it at run
time or something like
that so that's actually fascinating like
obviously I'm not going to go into the
type chicken right so that's too much
for today's stream we're not doing type
chicken uh but one thing I can do is
maybe introduce run time error uh so
let's go ahead and uh add the r
times uh so I
suppose mind FRS uh I
suppose we can return like a bu with
which indicates whether it failed or not
right so that's what we can
do uh another thing is that how do we
return the output of the node one of so
this node is actually accepted by a
pointer which is fine uh we can modify
this thing which is okay but it's kind
of weird it would be better to maybe
output that through another thing though
okay we can return node as a result and
if it's n that's a runtime
error that's fair
indication uh node error that which
propagates maybe right so we may
introduce special values for node error
and stuff like that but it's only needed
if we want to distinguish different
kinds of Errors which we probably don't
right now right so we'll make the
evaluator print the specific error that
happened and propagate up only the fact
that the error has happened so we can
exit with you know nonzero exit or
something like that because that's
easier right now like this uh so and
we're going to indicate the fact of an
error by returning no right since node
is pointer it's actually very easy to do
so I think I think that's fair anyways
uh so let's go ahead and do that so so
this more of like an expression right
it's more of like an expression and
funnily enough funnily enough um we
probably going to have like a evolve
function right evolve function or maybe
just like evolve Funk right so function
is too long for me and here we're going
to have a body and this thing is going
to return the color and again the point
of this function is to R the Evol right
simply rub the
Evol uh like so eval body XY so you get
the result right so this is the result
and by the way if result is equal to
null you probably want to return null
but you can't because
color uh but the idea is that you also
then check that the result kind is equal
to NK triple and if it's not equal to
Triple you throw an error right that
kind of the point so which kind of
implies that the corer has to
be um either returned through a
parameter which is I guess
fine which is I guess
fine um or something else um yeah so if
it's that we want to print
something uh but it's kind difficult to
tell what exactly is going on
here you know what you know
what I want to print the location of
where that
happened um we can employ a little bit
of a weird
trick we can employ a little bit of a
weird trick we can store the location of
the node
definition at least for now in the node
it's
self um somewhere
here we can say const Char file path and
also can have something like line and
you know where I'm going with all of
that chat you you probably know where
I'm going with all that so we can accept
a const file path and line in here so is
file path too much uh I think it's too
much right so let's just called file
right so this is a file and let's do the
following thing let's rename it to
something else right let's call it like
located or lock and let's
define uh node number which accepts the
number but then it calls back to this
thing macro time exactly exactly macro
time and in here we just do file and
this is going to be line uh right and
this is going to be the number that
we're propagating right so that will
expand properly into the information and
that information is going to be stored
within the uh within the node all right
so we want to put it like this in here
and this one is going to be node um so
it's file file and this is line so that
implies a lot of copy pasting and I
wonder if I can
somehow uh you know simplify the copy
pasting maybe I can create something
like
node right which accept node
kind and what it does it simply creates
the
node with the kind we supplied and also
obviously
with uh the
file and the
line and that just returns that node so
then later it is much easier for me to
do something like this
you know what I'm talking about you know
what I'm saying you know what I'm saying
it's just like much easier to do it like
that uh so then it reduces the amount of
copy paste that I have to do in
here um yeah that's kind of cool I think
so in in these specific situations um I
can even
simply just only accept this stuff this
is going to be lock and in here is just
an lock file line and where is the lock
and then I accept nkx and that's already
fully
initialized that's already fully
initialized which kind of also means
that maybe I can Define node
x uh like this that's just macro that
calls okay uh which also means that I
yeah I have to do something like
this yeah boy so and that simpli as I
can just do something like this which is
why
damn I wonder if I can
even do something like this right node
add LHS rhs here I can't okay I can't
easily declare all of that stuff yeah
whatever so we'll probably have to have
this kind of stuff in
here uh so yeah let's do const Char file
in line like so and in here we're going
to be accepting the node Lo uh file uh
line I I know that I have some typers in
here the compiler will tell me
eventually
hopefully uh right so we just do that
that automatically sets everything and
allocates everything and just returns
that so in case of
multiplication so we need to call this
thing I can probably do a little bit of
magic add Mt boom there's two of them uh
and let just impli I have to do node add
LHS rhs node add
look um it will
be I don't even
know yes like I'm still thinking how I
can simplify that and like reduce the
amount of copy paste but I can't really
think about a good idea right now so I'm
going to just keep it like this then
just going to keep it like this so let
me recopy paste this stuff and uh
re-evaluate all of that thing and the
triple is the last one so it's going to
be lock con Char accept this thing uh
triple just put this thing in here cool
so here we just do node lock file line
like so just set it up and there we go
and obviously we want to do the triple
in here as well triple uh first second
third uh triple loog uh can you see sh
Min friend first second third look at
that right let's see if it compiles
doesn't compile uh yeah so let's
actually go back into previous
instantiation of random pixels because
it's not ready yet and so that seems to
be working that seems to be twerking so
the idea now is when I'm evaluating
function and this is very important I
can now do the following thing uh s d
and precisely say where that
happened that is very cool
honestly right so um so function must
return triple
right function must return triple um and
that's it right so that's basically
everything I want to say and it return
false in here uh otherwise if
everything's fine if it is triple I can
now do the following thing R is going to
be equal
to so Coler has floats uh right so that
means I take result s triple first G
second B third
and I return
true so that's how we're going to be
going about that right so every time we
detect a runtime error we actually tell
you where where that runtime error has
happened and we tell that like where
within the source code you actually
Define that um so we can even put
something like a node
triple
um yeah so first need to implement the
evaluator thing right so first we need
to Implement evaluator and within the
evaluator we're going to be using this
kind of stuff extensively as well right
so let's go ahead and do that so I'm
going to be switch xer kind uh all right
and with for the node kind uh where is
the definition we need to implement all
of these things all right so let's go
ahead and Implement all of these things
uh all right so it's going to be the
case and boom uh break so in case of X
and Y it's actually super easy we can
return node number
X right so because we basically like it
wants evaluate variable X into its
actual value we know its value because
it was passed in here so we're taking it
from the
context okay neighbors are doing
something weird right so then uh we do
that if it's a number number just
evaluates into itself so we can just
return an expression then
okay that's very cool I can also align
this entire thing like that it almost
feels like I'm programming in a
functional language like in HK or
something like that or camel right isn't
so uh in case of an add all right so
what we want to do uh we want to First
evaluate both of these things right um
let me put it like this so this is going
to break so it's going to be left hand
side I
evaluate uh expression as B up left hand
side providing X and Y then I want to
evaluate right hand side but here's the
thing uh I need to confirm that left
hand side is a number and right hand
side is a number and if they're not I
have to throw an error you know what you
know what I'm saying you know what I'm
saying so uh if LHS uh kind is not equal
to NK number we're literally
implementing an interpreter we're
literally implement m in a
language so Isn't that cool I think it's
pretty freaking
cool that's so cool um so anyway
yeah oh funnily enough funnily
enough we need to
somehow oh I didn't even know
like so we probably need to pass the
location information Somehow Here uh chy
thank you so much for for the sub and
I'm sorry if I missed anybody so uh
yeah thank you thank you everyone for
for the subs so um if it's not a number
we have to say print F uh maybe
SD uh error and we're probably going to
be taking the location of the left hand
side in here so it's going to be file
which is yeah so this is the
file uh
and this is going to be this thing so
which is going to be the line uh
um expected
number all
right expected
number uh all right and we return null
right away we basically propagating this
entire thing when did to gener random
inte end up creating language SMH well I
mean it's not us who did that it's them
who wrote this paper so I think maybe
that's how it
went uh right so maybe that's how went
uh let's go ahead and do that for rhs
now right so here is the
rhs uh and yeah so we can actually now
yeah afterwards afterwards after we
confirmed that both of these things are
numbers we can go ahead and just sum
them up right so rhs as number we is sum
them up and that creates a new
number right and I feel like the
location of that number must be the
location of the original creation or
original expression right so because
that's what created it essentially so
there going to be
expression um
file file
expression uh line and because of that
this stuff also kind of the same all
right so
expression um file expression line we're
propagating it
further mm so it's it's sort of inherit
location you know what I'm saying uh
right you know what I'm saying uh and
then blames the scientists yeah I'm I'm
blaming the scientists all right so and
there we go so that's how we do that and
uh now uh we can repeat the same thing
for The Malt right so we repeat the same
thing for The Malt but we have to
replace
ads with more I didn't think there's
yeah there's no ads in here so but the
only thing we have to replace in here is
plus the paper gets around the type
validation Problem by simply only
allowing floats and simply having three
not trees one per color Channel maybe
that's what they do actually
um yeah that sounds
reasonable but no for
instance look at this
they have this weird RGB
node at the at the bottom so that means
they do have triple as a
note um so n not really so actually they
have a lot of different kinds of notes I
didn't look at the image only at the
sode yeah uh it's it's actually very
small right so we have to zoom in and
it's kind of bummer that they don't
provide the actual grammar they used and
actual nodes and stuff like that they
only kind of vaguely uh describe what
they're doing literally freaking
gatekeeping and also yeah they also have
mix node uh so they probably the actual
expression and grammar that they use is
super cool but they not going to
tell us they're not going to
tell us well I mean maybe it's described
here because after all this thing is
implemented in the SSH generation thingy
to to show stuff but I don't freaking
know uh it's it's obvious yeah yeah
exactly it's it's freaking obvious trais
thank you so much for for the sub thank
you thank you okay so they do have
triple um all right node first uh let's
do expression as
triple uh so first so this is the first
and second and the
third the third and we're going to I
suppose recombine it back right so it's
going to be node uh triple but this time
it's a lock because we're using the
original location
expression line first
second second
third all
right okay so that's the evaluator
that's our
evaluator uh let's try to compile it so
obviously it probably has some problems
uh number okay look at that and uh LHS
redefinition of LHS get fre Dam it
freaking
C this goddamn
language H old ass language with weird
ass scoping rules I mean it's I mean
yeah was all right for its time I
guess H
anyways anyways anyways anyways let's
just WRA all this stuff around number uh
what else what else do we have if well
so this one is a recursive thing so yeah
we we also have to accept X and Y right
so it's part of the scope right so it's
a scope variables in the
scope we have scoping in here okay so
this is the result and uh what is it
like it's not
compatible
ah ooh this one is actually fascinating
so it's not enough to check that it's a
triple you have to check it's it's a
freaking triple of floats and it's not a
triple of
triples um
yeah so
um you know what you know what know what
you know what I have an idea what if we
uh do the following thing uh expect uh
number right you provide the node and
this is just expression and we literally
just move this entire stuff in there
room so and
[Music]
yeah and we kind of have okay so we
probably have to provide the coin this
separately all right so this is the kind
and
um it's it's a bit bizarre but I guess
it's
fine so we also have to provide the
location
on file in
line right so then there later we can do
file and line and this is the co return
false in here or return true is it even
freaking convenient to
use so essentially what we're doing
we're replacing this thing with if
expected expect number LHS kind
and this
stuff and if it's not return
N I guess it is convenient to some
extent I guess it
is um right and then we can do LHS rhs
in
here uh
so and we can copy paste that
stuff and we can kind of do a similar I
think right you can expect
triple
uhhm
triple uh
triple yes
so you can do expect
triple uh result
kind expect
triple and we provide the
location and if it's not we return false
but after we checked all of that shis we
have to check separately
values
expect
number so first kind and also its
location right
also it's lo I wish I could just like
provide the node without location the
only reason why we are providing goddamn
location is
because well I mean uh so the things
inherit the things inherit their
location so there's no need to do it
like that right because if I evaluate it
that means it will use its own location
okay I don't need to do any of that
I don't know why it's decided to do this
way right so I can just like say node
exper right and this is going to be
expert kind and yeah okay so that
simplifies everything exper file exper
line right and then here I can do node
expert so this is a expert kind expert
File Expert line okay expect a triple
which simplifies this shy dramatically
stats and
that right so expect number expect
number we can even duplicate all of that
stuff uh well I mean we don't have to I
can just like remove
it so it's going to be actually kind of
Epic uh once it's done look at that so I
can do expect triple just provide the
result and then just expect number
second third look at that look at that
so yeah essentially we just
evaluated it evaluate it without an
error is it triple is the first one
number is the second one number is the
third one number okay so we're
constructing the final thing in here and
we're look at that look at that
very concise very epic very pretty
very
tight all right that's pretty cool so we
can maybe even say expect kind but that
means we have to make a mapping between
the kind and the name so we can use it
in reporting and honestly we not going
to have any other values except numbers
and triples anyway after evaluation so
who cares right so we're not going to
have a result of evaluation that is some
it's kind of stupid right so we the only
result of evaluation is going to be
either number or a triple so that's
about it I think um so that makes sense
that makes sense actually okay so
doesn't compile that
so uh so uh I don't I don't get it float
from node ah yeah so it's essentially
as a number right so we have to add this
extra look at that length right so we
know that it's a triple then first as a
number but we know that because we
checked all of these things first
yeah damn okay so and that works and
there's a control flow problem in here
so ah so this one is just unreachable
and unreachability is just to
evolve all
right holy
that was intense
BR uh okay so another interesting thing
we can do you know what I don't like
that I have to add Ln in here what if I
introduce like um like Ln uh right and
essentially this one is going to be
Define no um node print Ln so this is a
node uh node print node and just print F
Ln like so so what we can do we can now
do that and then uh a b with 0 0 so
that's what we can do in
here okay so that's before evaluation
this is after evaluation and since X and
Y are zero that kind of worked out we
can now assign X and Y half and that
works out right so this is before
evaluation this is after
evaluation see what I'm talking see what
I'm saying see what I'm saying it works
so this is an interpret it actually
works we can now the checks for uh you
know incompatible things for example you
can't add the triples right so we can do
node triple and we can just say
node uh maybe X right so let's actually
make three x's in here right and it's
going to be actually kind of cool
uh okay but but anyway it kind of
worked so here's the triple we're trying
to add the triple to Y uh right so
it's it's sack faulted right so let's
actually try to see where and why it's
sa faulted right so we compile with um
with the debug information so that means
it should be relatively easy to just go
into the debug wager uh all right go
into the debug
[Music]
Deb and uh just do ggb random art uh
let's run it and where did that happen
so um um yeah so node apparently turned
out to be empty right so when I try to
ah that is true that is actually fair
that is absolutely fair right so this is
the
result uh right so this is the result
and if the result is null we just return
out of this thing otherwise we print the
r because the null is an indicator that
it's an error
okay uh okay so
it didn't work bro it didn't
work so
that's okay maybe it actually crashed in
a different place maybe crashed in
ah we actually do Yeah we actually do a
lot of this weird things that we don't
actually
check yeah look at that we don't
actually check so one of the things we
have to do if LHS equal to no we can
even do something like if not LHS or
interal all right so and not
rhs uhhuh if not LHS
returnal not rhs return we can even do
something cool like a line return right
so this is kind of indication that some
sort of an error happened or maybe not
so essentially we forgot to Short
Circuit all of these things if first uh
not first uh return
no um
second uh third so that's very important
there's something that we doing here as
well maybe we should maintain the
pattern note results and return
false
yeah that that makes sense honestly that
makes sense
okay expected
number look at
that look at that
so yeah it pointed exactly that thing it
doesn't show the exact row but we can
maybe split it like
that okay it tells us that it expects
this thing to be a number but it was not
a
number right because it was a triple so
it tells us precisely where that
happened we can replace it with number
now which is X and that works out uh so
I think reporting is not you know
correct in the sense that it where is
the new
lines uh honestly that's like a lot of
code just
for um yeah just for reporting this kind
of stuff right if it was like more sound
type-wise it would have been easier to
implement but since we have we can have
situations where you have an incorrect
kind of as we have to write a lot of
code to compensate that uh which is
annoying honestly which is kind of
annoying but it is what it
is um
okay so render pixels right since we're
going to have this situation where
function is node all right and it may
fail it may actually fail which means
that rendom pixels should indicate the
failer somehow right so we're going to
return false in here uh so in case of a
true in case of a success we're going to
return true um all right so let's
actually get rid of all of that stuff uh
and in here we're going to be evaluating
the function right so might as well just
take a look at the signature right uh so
here is the function so maybe for the
sake of consistency I'm going to call it
f right because it's already called f
like that in here so here's the F we
provide n x normalized x normalize Y and
this is where we're going to be actually
getting the C
right so we're going to pass it by a
reference and EV Funk returns fals in
case of an error so if it's not that we
automatically return false so that's how
we propagate the runtime
error uh yeah that's it so now we have
interpretation of these things and stuff
like that so it's all interpreted now
which is kind of cool so let's try to
compile this enti thing and see if it
compiles properly no it doesn't compile
because now cool uh
right render pixels does not accept
pointers to the functions anymore it
accepts a so one of the things we can do
we can try to Port our native C
functions to interpret it once through
the EST for example here gray gradient
used to return uh three X's we can
encode that by making uh node triple
node X and just like uh 3x is like
so and that already basically an
equivalent of that gray gradient
function that we implemented so we
actually implemented it as
as right so Isn't that cool I think
that's pretty cool so we can even format
it like that uh so it's going to be x x
x right and obviously it can fail uh
right so we can do something like this
if uh not okay right if not okay just
return one and that's it just forget
about it uh right so let's actually try
to run it and that seems to well I mean
I forgot to remove that code that we had
in here so it's just a testing code
nothing particular special uh yeah and
generated output let's take a look at
the output uh it's a gradient here's an
interesting thing um so I can now change
this x to
Y and the gradient should be where's
vertical so look at that look at that so
we now write functions not in C but in a
of our new language that we interpret
them look at that look at that uh so
this is actually super cool can your SE
we literally Implement that in C right
uh we literally Implement that in C so
we can maybe do some things like x y y y
right so how it's going to look
like so
yeah as very cool so what's funny is
that the function the value of the
functions are independent of each other
so we can theoretically even parallelize
that who said we can't do that in
several threads but it's kind of like
outside of the scope of today's stream
we're not going to be parallelizing that
but we can do something like that we can
do something like
that uh so yeah it's almost like
implementing your own Shader language or
what not that's what it is like it's
it's your own shadow language right it's
just like you executing it on CPU uh so
we can try to do the cool thing uh right
so so let me let me put it like that so
what was the we didn't have an yeah we
can't encode
ifs look at
that have if then
else
and the fact that they have if then else
implies that they have booleans as well
and the fact that they have booleans
implies that oh oh my
God so now we need to add this kind of
node in
here compile to spe and run with Vulcan
yeah do should we add this node should
we add this
node so that sounds like a to be fair we
already have all of the necessary
infrastructure to add this note so it
shouldn't be that hard um all right so
let's go ahead and do that so this is
going to be well that that implies we
need to add also greater
than
um um that's that's bizarre honestly
that's bizarre how how can we do that
um
so so we have number we can have bu okay
so let's introduce bu I think it's going
to be
interesting uh all right so it complains
about lack of this
thing uh and for the bull we can do
something like
NK bull uh right so print
FS note as
bull uh let's go boan and if it's true
it's going to be true otherwise it's
going to be
false like so so that means
here uh node
s uh where is the node
s uh so this is going to be bull buan
right so we have that uh and evaluation
here is rather interesting so it's a
bull and we return it as is surprisingly
which means that we can kind of actually
do something like this yeah so Boolean
and numbers are returned as is uhhuh so
and in here um yeah so we have to break
here we can't really construct them per
se but I guess that's
fine I guess that's fine so um now we
need to introduce greater uh right
so let me see so if it's um I'd like to
put it in here so here is the number and
operation on the number so we can have
Boolean and operation in a Boolean so
this one is
greater go GC so let go to the
compilation errors um all right so here
is the number and operations on the
number so and this one is
GT uh which I suppose I'm going to wait
wait what did I what did I do I
just move that stuff ah so I want to
copy paste that stuff this one is going
to be uh GT and it's going to be a left
and right thing all right so enumeration
evaluation uh so this one is rather
interesting uh what we need to do we
need to do GT we evaluate left hand side
check that it succeeded here we expect a
[Music]
Boolean no we expect a number we expect
a number and in here we're actually
doing not a number but a
Boolean which is going to be one number
greater than that that's how we're going
to be doing all that so but we don't
have node Boolean so we have to create
it honestly it actually makes it rather
easy to extend relatively so could
replace number Boolean like so and this
one is going to be just
bull you know what I'm saying you know
I'm saying I think I think yeah enk
bull you know what I think I want to do
that
bull ink boo well I mean the compile
tell me so let's just call this thing
Boolean okay so this one is going to be
Boolean this one is going to be
Boolean there we go okay that's cool so
now we have booleans we have greater and
now we can introduce if right so um
let's have something like NK
if um
maybe condition right so let's go
through the compilation so in case of a
condition this one is rather interesting
so
NK ah I don't like cond let's called
[Music]
if so what are we doing we're printing F
uh
if maybe
space afterwards we do node print note
as we can't use if it's a reserved
keyword so we're going to call it if so
we're going to print condition all right
so afterwards we're going to have it uh
then with a space obviously then we're
going to print the then part uh then
we're going to print the else part which
is going to be else but the word else is
already taken we're going to call it
else uh and yeah that's about it so
that's how we're going to go about that
uh so we'll have to create all of these
things as you can see there's no such
thing as if node as uh here we're going
to have
if right so an
if uh type Dev struct is essentially
node if so it has a condition which is a
separate node right so node than
else so that's the as we're dealing with
so here here's another switch case so
evaluation of if is rather interesting I
think it's going to be rather
interesting so K is in K uh
if
um so what we do essentially we have to
evaluate all condition then and else
right so that's what we have to do so
node uh condition so Evol expression as
if condition X and Y let's check that it
didn't fail right so it didn't fail uh
otherwise return n and then we have to
verify that that specific thing is a
Boolean right so we can say um expect
Boolean right so we say con expect
Boolean and if it's not a bullion we
return null okay so now we can construct
the following things so we need to
actually uh evaluate else and then all
right so it's going to be then and else
I mean so let's put it like this then we
should not forget to check that it
didn't fail right and then we're going
to check then else boom we have as then
and else and what we do we're checking
con as Boolean if it's true we return
Then otherwise we return
else oh kill me already um
so
all right so we have that uh all right
so we have that kind of so expect
bulling uh expect uh number you could
lazy I could but I don't want to I
already did it in a more eager way so
replace number
Boolean so and the one of the reasons
why I want you to call it NK Boolean it
just makes it easier to like replace
query replace things
okay so what is it like in here so it
wants to have break and it seems to be
working so here we have if so we have
greater booleans if and we need to have
mode Let's introduce
mode okay so in K mode this one is going
to be actually very easy right so it's
just not that many of them so because
it's basically like malt I can just
query replace maltt with mode malt mode
there we go next and in interpretation
is
basically something like this all right
where we
replace also mold with Mod but this one
is going to be F mode
F yeah and as you can see like these
patterns can be compressed in here the
uh the patterns of the binary operators
definitely can be compressed that's for
sure uh there we go we have we have all
of that in here we have all of that
in here so um yeah how are we going
to be approaching all that so if I want
to have cool
right let's go ahead and do that so this
one is going to be that and this is
going to be okay okay um we want to have
a
nod
if okay not if what's the condition we
take multiplication of X and Y so node M
node X and node y That's the condition
in here and we're checking that not
greater uh this thing is greater than
zero that's what we're checking right
that's our
condition uh if this thing is greater
than zero what we essentially return is
a triple right where we have X and
Y uh Y and a
number one that's what we do otherwise
we return a different triple node triple
where we
have F mode uh WR mode between X and Y
and we have three of such
things
right right
look at that so that's basically the
encoding of that cooler function that is
supposed to generate uh that gradient
somewhere I I don't know where it is uh
yeah this
one this one and obviously it's not
going to because we don't have some of
the functions in here uh maybe we can do
something like this to sort of make it
pop to make it obvious what exactly work
doing in here right so node if so this
is one node this is the then and this is
the else right so we're going to be
constructing that uh right so let's
actually see uh is it working is it
working so we don't have no if right so
let's go into the not triple uh right so
and there should be this thing what I
can do I can just query replace triple
with if boom uh so in this specific case
I actually want to call this thing if uh
the first is going to be the condition
right the second is then and the third
is
lse see what I'm saying see what I'm
saying Okay so let's align like
that uh that's pretty cool so we have if
condition now uh what else do we have in
here so node GT okay malt uh okay so
this one is going to be mult GT
boom what else mode okay
Mal
uhuh uh C Place M
mode what else node y so this is
actually
function okay and it terminated by seful
that's
cool uh so uh
we should take a look at
the at the GDB so it's I probably forgot
to check some of the um you know
evaluation results right some of the
evaluation results uh that's probably
what I forgot to check okay let's go so
it failed uh at eval uh to we enable
yeah obviously it failed at eval so
exper turned out to be empty all right
so which is and this well so it's
probably localized to just evolve right
which is understandable so if it's not
null we return that so all of that stuff
is
fine uh expect
null honestly uh node number zero node
number
zero H what are guys talking about how
the does it help me to find the SE
fold
greater ah o this is actually annoying
what the
this is insanely annoying why the
compiler didn't tell
me oh my God so this is dangerous right
bro so because because of no oh freaking
C God damn
C goddamn freaking yeah because null is
literally
yeah why do we still program in this
language can use rust this is a fallacy
bro bro bro bro bro bro bro this is the
freaking fallacy that the rust deaths
want you to believe right so they pick
on like a very small problem in C and
instead of solving that specific
problem they propos to use this over
bloated ass language just no this
this is like a like
a this is some sort of a propaganda
level like get out get out of here
uh all right so we've got this kind of
stuff does it work uh yeah it does it
produces what we expected it has this
thin thing in here but I mean
whatever uh so and now uh we need to do
this kind of thing so if I switch this
kind of stuff uh all right
that that works but I mean the original
thing was uh the gray
gradient okay so we implemented this
idea where we have the
as the
as uh so that was actually that's a lot
of code right so it's a lot of copy
paste luckily it's very easy to copy
paste so uh wasn't that hard so it's 400
lines of code holy but anyway but
anyway now instead of writing this stuff
yourself right instead of writing this
stuff yourself what we have to
do
is generate using using
grammar
o that is special my FRS that is
special so and essentially grammar is a
context free grammar so context for
grammar is the grammar expressed by BNF
It's relatively easy to do uh yeah so in
essentially what we have to do we have
to kind of
inter grammars and nodes nodes must also
like must have a kind that
is like a grammar
variable then that is very deep honestly
that is very
deep because we need to be able to
express this kind of thing so okay
grammar rules let's say that the grammar
rule uh is going to
be um it's called
Rule this is the
rule
and I suppose the grammar rule is going
to be just
node okay if it's just a node that means
grammar uh grammar is just a sequence of
noes if
anything but what we want to do honestly
is kind of Define it
dynamically so there is a flag for zero
as null point a constant option thank
you I already kind of passed that so
uh all right so grammar chat cannot keep
up uh grammar so grammar is going to be
a sequence of nodes right so it's a
pointer pointer because nodes is pointer
right so it's going to be a capacity and
it's going to be
count right so that's what we have
here uh
and nodes should
have
um a special kind
uh
grammar yeah so let's go through the
grammar and when we're printing the
grammar the grammar itself know
as
uh has to be an integer and it's going
to be an index within the grammar array
so the grammar is going to be an array
of rules and you see how some of the
notes in here some of the notes in here
refer to
grammars right so for example C is
defined in terms of itself so it's self
referential so and that node is
describes that describes that and it's
going to be an index within the dynamic
array something like
that it's going to be an index within
the dynamic array um so
that is very cool so let's go to the
compilation when we're printing this
entire thing like how we going to be
printing the grammar thing though how
going to we printing the grammar
thing uh so K is and K
grammar um so I I guess I'm going to
just quote grammar right so grammar Z
and it's going to be not as grammar
Exel in case of interpretation
that is a runtime
error right if you're trying to
interpret a grammar rule that means your
grammar was not expanded properly you
can't evaluate
that you can't evaluate that so and that
means we'll have to report an error from
that so it's going to be literally null
uh right and it's going to be just like
a print
F uh right um so
SD SD
cannot evaluate grammar
rule right it's probably F and I just do
expression file expression line and
that's
it okay so what else hand here uh I
didn't like uh yeah it's just break
that's understandable all right that's
cool how are we going to be defining the
goddamn grammars how are we going to be
defining all that look at that
so e we're not really referring to e
anywhere so this is sort of like an
entry okay that's understandable so I
suppose we need to Def uh start defining
it from
here uhhuh okay let me let me think so
this is going to be grammar uh
grammar uh so we're going to have
something like
C grammar
count what I want to
append into the grammar as a dynamic
array is just a
node so we need to have this or
nodes not only the grammar nodes but
also or
nodes okay so ink let's call it
actually rule
maybe I'm going to just call it like
like this all right so uh this is
Rule uh Rule and I also want to call
this rule in grammar rule because
grammar is a collection of rules right
so and this is a single rule of the
grammar all right so this is the rule
about grammar rule so that's correct uh
right so it complains about that so but
this is because I'm just like okay so
that's that's understandable
all so I need to introduce another one
um which
is rule
or
um so and what's funny is that you can
have several of them how are we going to
be supporting several of them we
probably can Nest
them I guess that's way we can do that
like we can Nest them
essentially um yeah but this one is
going to be kind
of kind of
interesting we can simply Nest
them
mhm maybe I need to make a small break
honestly maybe I need to make a small
break so yeah so this is already like a
third hour uh and a little bit of a
break would be nice right because I'm
almost there like we implemented all of
the necessary components of this system
uh right so we have a renderer engine
that given a function can render an
image that's fine uh we have a no like a
interpreter right so that means we can
Define functions in terms of as so now
we need to implement the grammar
generator right so this is the last
component of this entire thing and as
soon as we as soon as we have that we
have the entire basically system uh
proposed in a paper uh right so with
probably fewer nodes but nonetheless
right so once you have this of like a
system you can just add more nodes in
here right you can just add more nodes
so I I need to implement the grammar
generator so let's make a small break
maybe right so and I'm going to refill
my C of te and then we're going to
finish it right because it doesn't seem
that difficult I think right doesn't
seem that difficult or does it right
because yeah then I'll have to implement
this recursive algorithm that does the
thing maybe I should split it into two
streams let's split it into two streams
right so I think I'm going to go sleep
and tomorrow we're going to continue and
finish the Gramma generator yeah so
because like yeah I don't want to over
stretch myself so let's let's put it for
for tomorrow all right I guess that's it
for today thanks everyone who's watching
right now really appreciate that that's
super fun right so this a very this is a
very cool system in the sense that it
requires you to implement
sort of like interdisciplinary things
right so because you have a little bit
of a computer Graphics in here right and
also a little bit of a language
development it's just like this is so
cool right it's a very interdisciplinary
thing and I really enjoy that
and I really want to finish it and I'm
going to finish it tomorrow all right
thanks everyone for watching uh right so
thanks for all of the subs reubs Rec
commitments thank you thank you thank
you really appreciate you yeah and I see
you all tomorrow uh I love you all um
this is the next day and let's continue
developing this thing right so we were
in the middle of developing the grammar
stuff so I need to recall a little bit
on what exactly I was doing so let's
actually check if this entire thing
compiles all right uh right it does
compile but there's a couple of warnings
in here ah okay so we were in the middle
of introducing a new node called rule or
right and that node is specifically to
combine together several rules of the
grammar right so basically here you have
either a or add Cc or or M CC with
different probabilities by the way so as
you can see they are kind of like you
know you can have or that contains like
three branches so as of right now uh we
have node as that is Bob so what I was
thinking yesterday I thought maybe I'm
going to imp rule or as basically a
sequence of Bops right nested Bops but
this is not really convenient honestly
it would be better if it was like a flat
array and not only flat array but I also
could have an association with
probabilities of certain branches in
here like they do in the paper right
because they don't just encode this
stuff like that they also encode
probabilities with which probability you
you have something like this um right so
maybe because of that I'm going to
introduce a special node in here which
is like literally node rule or or and uh
so
essentially uh what I'm going to have in
here is like a sequence of other nodes
right so we can have something like node
um items right so this is going to
become a dynamic array so this is
capacity and uh this is a good
indication of this thing being a dynamic
array but unfortunately this this does
not include the probability so that
means we probably need
to uh we need to have some sort of a
separate structure I have no idea how to
call the structure but it's going to
contain a node and a probability right
so maybe we can do something like a
probility as a float and like node rule
or is going to be um basically a
sequence of those branches maybe we can
call it something like nde node rule um
branch right so this is basically branch
and uh here we can do node rule uh
Branch so basically this is a single or
and uh these are the branches they
contain the node and the probability of
that node uh I think that makes sense
right so
anyways anyways anyways anyways though
in all
honesty in all
honesty
um we can just
make this thing doesn't really have to
be a
node if you know what I'm talking about
it doesn't really have to be a Noe
because at the it is at the top level of
the
grammar right it is at the top level of
the grammar and uh because of that we
can just have a grammar rule right so a
grammar rule uh which by
itself
is a sequence of these things so yeah it
doesn't really have to be its own node I
just realized that it doesn't really
have to be its own node right because
like already said it's just like a top
level so we can try to remove that so
internally the nodes will contain the
reference to the rule right so but then
we're going to have something like
um um
maybe grammar branches we can maybe even
take node or where is the node or did I
already remove that uh node um rule or
we can take all of that
stuff and just reform it somehow right
so this is a grammar rule Branch uh
grammar rule Branch this is a single
Branch uh of this thing then uh grammar
um grammar rule
branches branches and grammar is
basically a sequence of these grammar uh
rule branches several of
them um maybe it doesn't really make
sense to actually call them grammar rule
uh right we can call them grammar branch
and grammar branches right there we go
so there's a single grammar Branch uh
which contains like a the note itself
the expression right and then the
probability of that expression and then
here is the sequence of branches and the
grammar is the sequence of these grammar
branches right so this entire thing
encodes this thing this grammar so this
is the
structure so that's basically what we're
doing in here hopefully it's
understandable hopefully it's
understandable so the these three
structures I'm just trying to encode
this
stuff U hopefully it will be able to do
that all right so let's try to compile
this entire thing and go to the
compilation errors uh yeah did some
Walky uh okay so grammar branches
yeah it should
be uh grammar Branch right so it's that
and it seems to be compiling so that's
pretty cool that is pretty pretty cool
so that also means that we have to
somehow construct those
things separately if you know what what
I mean we have to like construct them
separately first we have to construct
dynamically grammar branches By Di
appending them di appending them and
then once we finished constructed a
single Branch we have to append that
Branch into the grammar that's how we're
going to be going about that right so uh
we already have diend uh implemented in
kn. H but the thing about diend is that
it uh allocates memory right so we don't
really use diend anywhere right but we
do allocate memory into the arena so and
theend actually allocates memory using
Malo from the leip c um but since we're
doing dynamic memory I think it would
make sense to also for Di aend allocate
all of that stuff within the arena
itself as well right so now we need to
make the DI append from no allocate all
of the memory within this specific Arena
funnily enough I think I do remember a
little bit that within the arena I
implemented di append yeah Arena
implementation has its own di append
that supports that Noob format of
dynamic arrays and allows you to
basically work with Dynamic arrays and
allocate them within that specific Arena
holy
that's so cool
uh right so that means I I don't really
have to use this di pent from no and
allocate memory dynamically using the
lipy Malo or and anything like that I
can just do uh right so Arena di append
and I I'm allocating within node Arena
like so uh right and all of the memory
that is allocated for that specific
Dynamic array is going to be allocated
within that Arena so when I de allocate
it uh right so it's also de Ates all of
these Dynamic Aras things it's actually
kind of cool I really like that so uh
here is the arena write a dynamic array
and items and it just like allocates all
of that stuff in there so Arena library
is actually insanely cool I really like
it okay so we probably as I already said
we're starting constructing from
branches right so let's introduce
something like a grammar Branch let's
try to encode this specific grammar that
they have in the paper right so the
startat with e right so they start with
E all right um so so we're going to have
a basically a single
branch and into that Branch into that
Branch we are so there's only one triple
in here right there's only one triple in
here which is understandable so let's do
node uh triple so how can I uh more
convenient to do that uh and here this
triple refers to three sees each of them
is a branch within the grammar right so
we encode the branches with the node
which is node Rule and I think I need to
re uh rename it to grammar or maybe to
brunch or something like naming is is is
surprisingly hard within this project
right so how exactly do I call that I
don't really know but anyway so it's
going to be node
Rule and it has to be C but what's
interesting is that c refers to the
third branch in here and the third
branch doesn't really exist so I don't
really know what to put in there right
so maybe for now I'm going to just put C
because I want to code it out like
this uh right so branches and grammar
are fine names I think yeah I guess like
for people who watching the the current
stream maybe it's fine but what if you
just reading this code for the first
time like is it understandable I I don't
know anyways uh so here we created a
first Branch here we encoded the first
Branch uh and now we need to append it
into the grammar right so we want to
have a grammar uh and here is the
grammar that we are working
with
mhm uh
honestly honestly you know what I'm
thinking because of how we
are doing all of that because of how we
doing all that maybe
it just makes sense to n let's keep it
Dynamic I was thinking maybe I should
make this thing a static array but I
don't think I can easily do that
unfortunately I don't think
so
[Music]
um all right so here is e uh here's that
and I'm have to do something like Arena
di append uh node Arena obviously I want
to do that within the node Arena and I'm
basically putting that into the grammar
uh right and what I'm putting in there
I'm putting this Branch but after that I
kind of want to reuse the same Branch so
I have to reset that Branch like this
right so I have to reset that Branch
like this since I kind of know how many
grammar rules I have on here maybe I can
say that c is going to be the second one
right so we can basically assign indices
on each an individual Row in here so
this one is going to be zero and every
time we refer to e anywhere in here
we're referring to zero so this one is
going to be one and this is going to be
two so every time I refer to a I'm going
to refer it to one and C is going to be
two so in here uh what I can do um is
basically so this has to be actually
node rules three node
rules uhuh like so and they are in fact
two but maybe we can do something like
two right so we can assign e equal to
Zer then a = to 1 and c equal to 2 I can
literally just use them in like in names
in here right I can literally use them
like that okay so then I appended the
branch um and then I reset the branch so
now I need to create another rule in
here um right so it's going to be Arena
di append node Arena so what I'm
appending into the branch I'm appending
like just a random
number uh just a random
number so that
means that grammar
stuff is supposed to be able to Generate
random
numbers mhm so we need to add another
node in here honestly we need to add
another node in here so graor thank you
so much for uh the twitch Prime thank
you thank you thank you so let's go
ahead and add another node so node kind
uh so here is the we have a rule and and
K random so let's go through the
compilation erors uh what do we have in
here so uh random uh yes so here's the
rule
K and K um random right let's going
print
F uh random so I didn't I think yeah I
don't think it contains like anything
right so it's going to be just just like
that uh but this random for every user
just set to random value um is this
random for every use this is only for
Generation this is only as part of the
grammar right so this node is going to
exist only within the grammar then we're
going to take the grammar and give it to
a random generator of functions based on
grammar and that random gener generation
or generator of functions based on a
grammar is going to see that node and
replace that node with a random number
solidifying it for the current function
so this is only part of the grammar but
as soon as a function instantiated out
of that grammar this value is going to
be very much specific that's basically
the idea thank you so much stupid
engineer thank you thank you thank you
uh right that's basically the idea so it
only exist in here we have a really
interesting set of kinds of nodes in
here which are valid in the grammar
description but are invalid in a
specific instantiation of that
grammar right you know what I'm talking
about it's kind of weird and using these
nodes in a specific instantiation of the
grammar is going to be runtime error
right it would be nice if it was some
sort of like a compile time error but we
don't have a compilation step in here um
right uh um we don't have a compilation
step so I planning to bring back porch
development what is porch development I
don't really know what is
porch okay so let me let me see let me
see let me see so um we are yeah so we
need to introduce the random node uh let
me know so when we are we are evaluating
it's going to be similar to rule right
um
we can do something like NK random um
cannot evaluate a
node uh a node that is valid only for
grammar uh
definitions right honestly I really have
an urge to have like
a array that Maps a specific kind of a
note to its name right because it's it's
it's really convenient so let me maybe
Define that right so I think it's going
to be very much useful to to have it
somewhere in here so um we can maybe
Define something like a count and K
right so that will give us the amount of
enumerations that we have in here uh and
then we can define something like NK
names right so it's going to be count in
K uh and in here for each of them we're
going to have
name so I'm going to copy paste those
things in here uh I'm going to remove
all of the white spaces and maybe we're
going to use a little bit of a emac
magic look at that ch ch look at that
boom so and we're going to map them to
like strings in here I'm going to put
the string in here
and uh maybe I'm going to keep them like
this maybe not it's kind of hard to tell
but anyway so we can also align those
entire I think and there we go so we
have an array of names in here um so
what's funny is that when we modify the
amount of nodes in here right so when we
add another node we may easily forget to
update this array right so there's no
nothing in the compiler that uh makes us
to like just keep this array exhaustive
if you know what I mean uh so one of the
ways I do that I just just do static
assert and I just say count NK is
expected at compile time to be equal to
the amount of lines in here which is 12
right so and if that value changes that
asserts fires up reminding us that we
have to actually update this list of
names so it's kind of like a um
exhaustive switch case right but for
arrays so that's how I do
that uh so uh amount amount of nodes uh
have changed so I'm going to keep it
like that static assert in C is actually
very good
feature uh very good feature allows you
to do things like that okay so we can uh
we can take a look at that and of course
since we added count uh count in K all
of the switch cases became
non-exhaustive but count in K is kind of
a special value that you should not
check anyway so what I usually like to
do I just like to put count and K and
straight uh fall through into the
unreachable right so that's what I like
to do right so if you got this thing
it's it's also invalid so it's also
unreachable um right there we go what
else do we have in here the same thing
in here so ske count and K also
unreachable just fall into that uh what
else do we have in here so it fails
somewhere in di append it doesn't like
something in here um right has no oh
grammar Branch doesn't have a
count I
see because
why ah right because we're supposed to
not only uh put a node in here so that's
just a node but we're also supposed to
put a probability of that node during
the generation of the grammar right so
and that means we have to use a little
bit of a cital pattern right so which is
basically uh grammar grammar
Branch right so the naming for those
things is kind of wonky because I
haven't figured it out yet right I
haven't figured it out but as soon as I
figured it out I I think this entire
thing is going to be a little bit better
uh all right so what else do we have on
here it still complains about this thing
uh so it's okay
Branch
branches so this is branches brand
cheese brand
cheese there we go it's a brand cheese
node rule we don't have a node
rule so how can we create on so maybe we
can actually use node number right and
literally just rename uh number with
rule boom look at that and then we can
replace this float with this integer let
me take a look at the node rule uh do we
have a node rule or is it called
um uh
oh node ah yeah here it is so it's just
that all right right right that makes
sense okay so let's try to compile
so branes count brand cheese and
everything seems to be compounding so it
complains about this thing being unused
but that's fine that is totally fine
okay so everything seems to be Okie
everything seems to be Ki so I feel like
you you must actually uh put this
parenthesis in here because diend is a
macro so it may not work easily right
away yeah you have to wrap it like that
because this entire thing contains
commas and the preprocessor of C think
that you actually separated like this is
a separate argument and then this is a
separate argument of the macro oh my God
freaking uh freaking C preprocessor I
swear to God uh
so you guys know what what I'm talking
about you guys know what I'm talking
about so if fu is a macro not a function
to time to pull out M4 yeah I guess
that's the time to do to do that so and
if you pass something like a b and then
c d the preprocessor does not see that
as three arguments it doesn't see it
three arguments it sees it as four
arguments you know why because there is
a third comma in here because what
you're passing into the preprocessor you
passing a sequence of tokens so here is
the first sequence of tokens you passed
then comma another sequence of tokens
comma another sequence of tokens so it's
a third argument comma and the fourth
sequence of tokens
to tell the pre-processor not compiler
pre-processor that it's actually three
arguments you have to rub them into
parentheses so and this is insanely
annoying especially if you refactored
your function into a macro later so as
soon as you refactor your function into
a macro you literally have to Now call
them differently if you pass structure
literals in here it is insanely dumb it
is insanely annoying it is insanely dumb
and I freaking hate it but that's what
you have to do so uh that actually kind
of forces you to always rra all of your
um you know cliteral structure literals
right into parenthesis just in case in
the future this function will be
refactored into a macro
right why why do we still program in
this language right so why anyways
just use
R
anyways uh okay so what do we need in
here what do we need in here so the next
grammar is just a random
number okay
good so node uh and it it's just a
random number so node random it doesn't
really have any particular value right
so it's just like a template thingy the
probability of the random number in this
specific case is
1/3 right so I guess I could put 1/3 in
here um something like
this so it's it's kind of difficult to
represent 1/3 uh in i0 754 cleanly if
you know what I'm talking about right so
is because of this so we kind of lose a
little bit of the Precision uh right
maybe to not lose any Precision I
literally have to use fractional numbers
in here uh right so I don't know but for
now I'm going to just use the floating
point and just assume that yeah we do
lose a little bit of the information uh
but ideally I think we should have used
fractional numbers in here and
fractional number would be literally a
structure uh right which is the what is
the numerator and denominator right so
num uh Den or whatever something like
that and we would Define operations on
numerator and denominator right so we
would do gcd algorithm and so on and so
forth and that already feels too much
outside of the scope of the stream uh
right so I really don't want to do that
so I think we're going to keep
probability like that even though we'll
lose a little bit of information right
so it's fine it's going to be fine chat
it's going to be fine all right so
what's the other Branch we have in here
which is X okay so that means I can add
another one in here and node X and this
is also 1/3 and another branch in here
is y also 1/3 uh and after that I'm
appending that new Branch to the grammar
right and I'm cleaning it up literally
clean this one is actually kind of
dangerous because that
literally will make um the memory be
reused on the next append yeah it will
make it reused on the next append so
what we probably want to do in here is
not really set count to zero but
literally set everything so M Set uh
Branch branches zero size of
branches basically effectively creating
a completely new branches every time
that's probably one to
do uh you could use one of this Russian
old school Turner computers to get
exactly oneir why people still talk
about this computer right it's kind of
like it doesn't make sense uh in the
current
age so I looked into this computer and
what I found after brief looking is
that it just at the time at that
specific time with the specific
technology people used to make memory
economically it was cheap
but now the way we make memory is
completely different and it
doesn't make sense at all today like
this tary computer it's just a cheaper
computer of its time it's a thing of its
time and you can't really use the same
idea today but for some reason people
still still talking about it this is so
bizarre to me right I think it's like
from the times when people used the
magnetic cores magnetic rings to start
memory it's from those times
right it it sort of became like a meme I
suppose uh didn't they find that it's
better for uh computation or something
too I don't
know um also more stat is better maybe
like from what I heard from what I read
it felt like it's the only Advantage
this computer had is purely economic one
like purely economic
one um get the P that work isn't turn
the best counting system in some
aspect I don't know we we can talk a lot
about like different shapes of the
plugs but at the end of the day we're
going to be used the one that is more
that the most common one around the
world right you know what I'm saying
right I'm I'm pretty sure certain shapes
of plugs are more convenient than the
others but the infrastructure like you
know build completely differently so who
cares it's the same thing with C nobody
lies this shitty language but
all of the infrastructure is buil around
this language anyway so we keep using it
so just like
yeah some shapes of the plugs are better
than the others so what like we stuck
with whatever we
have it's just like my my opinion of the
situation maybe it would be cool but uh
to have Turner computers but that kind
it requires completely going back into
the times when this infrastructure was
not built around the binary computers
right so and start from scratch but is
it really worth it at this point um you
is the best
yeah
uh like I said the ultimate reite from
binary to terer yeah the big rewrite the
big
rewrite anyways uh so we just openend
this thing and uh instead of like
setting it to zero we can look at that
so and what's interesting is that
there's not that much information about
on computer in English right so but
there's a quite like there's a whole uh
page in I think MSU like a Moscow State
University or some other university
about that specific computer the
University where it was designed they
have a lot of information about it but
it's all in Russian so like I have it on
my do list just like at at one day like
sit down and just like read all of the
materials that they have on that
computer um so maybe even translate it
to English that would be
interesting to computer that would be an
interesting stream actually so because
they also have a little bit of like a
source code written for that computer so
like write an emulator for that one huh
that would be cool I should think about
it all right so uh here's the other
Branch right so and yeah this is just
like a three branches in here and this
is a leaf grammar rule uh there a leave
grammar rule so the last grammar rule is
going to be this one um so let's do
Arena di append node Arena brand
cheese grammar so did I actually named
Grammar with a single M why how did it
compile excuse me why why does it it
doesn't compile
obviously uh right so because it's it
has to be double
M yeah so but I mean I also have to wrap
it with parenthesis
obviously because of the macros uh right
node random declaration does not exist
so I think it's kind of similar to these
things right so we can have random and
this is a
random uh I need to create a system
where defining new node uh Constructors
is as easy as the as this right
so maybe even have node
Lo that kind of
maps um you know so it can takes VAR ARs
and maybe it passes those VAR args in
here and inside of this thing it sets
them somehow uh X macro no X macro does
not allow you to have defin so you
cannot uh you cannot Define a sequence
of defines through X macros
unfortunately I wish you could but you
can't do
that uh that's not something that c
allows you because it's a shitty
language but anyway uh and also if we
have this thing as empty this is not
going to work because V ARS can't not be
empty oh
sake get Dam C get Dam C but we're kind
of stuck with it anyway so
uh kind of stuck with it anyway all
right so maybe I can use a little bit of
a emx magic to smooth out the
pain okay did I manage to smooth out the
pain I think I managed look at that I
smoothed out the
pain absolutely marvelous uh all right
so grammar branch and in here what's the
grammar Branch it's a so the node is in
fact node Rule and Rule is a as you can
see right so a and a is one in here
makes sense so and the probability of
this thing is what it's 14th look at
that it's 1/4 all right can I actually
do something like one fourth I should be
able to do it like
that so let me try to run it uh yeah
obviously the
parentheses uh
parentheses okay I can copy paste that
stuff so the next one is going to be add
okay so node add but we're adding
together two rules in here so that means
it's going to be node rule C node rule C
that's what it is the probability of one
38 okay 38 it is then
38 uh okay and now so what we doing here
so this is the same but multiplication
and the same prop probability as well so
afterwards we're appending the grammar
we're just appending the grammar and we
go we just defined the grammar believe
it or
not okay so maybe we can yeah maybe we
can do something like that is that is
that better it doesn't look better
honestly uh right so look at that so we
have three branches in here so this is
the first Branch the E uh this is the
second one one that consists of three of
them right so the first one the second
one the third one so here is the three
of them so that thing and that's the
last one which also contains of three of
them so this is the last one so we
encoded this small thing with this much
code in C can you believe that so this
is how much code it took to Define 36
lines of code maybe a little bit better
because it also includes the definitions
of all of the structures um right so 42
lines of course in that case
so what I was doing this entire time I
was just like trying to convert this
thing into C code so we can then uh
Traverse it recursively and maybe
generate some instantiations of the
functions and stuff like that so that's
what I was
doing maybe there's a better ways to do
that but uh this is the one that I can
think of right it's a little bit painful
but it is what it is and I wonder if we
can just like somehow dump that grammar
just to see what it looks like uh that
would be interesting I think so let's
Implement a printer for this things so
we we already have like a print nodes oh
we have node print right so we have a
node print we can Implement grammar
print uh right so accept the grammar uh
grammar there we go and in here we just
like iterate the branches and yeah so
let's just go ahead and do that so size
TI less than grammar is going to be
count Plus+ I right and for each we're
going to do the following things so this
is going to be
Zu uh so we printing I so we identifying
the specific line in the grammar by its
Index right so here they have a
privilege of using numbers right but we
can't do that like numbers letters I
mean letters letters but we can't do
that so we have to use numbers
unfortunately so and that's what we do
when we dump in this entire thing as
well maybe we can use like a BNF
notation right so is that how you define
like uh rule in a BNF right I think
that's how we do that so and afterwards
uh we have to just do node uh print and
we probably want to print a new line
here anyway so I'm going to put Ln in
here so it's going to be no print so
what does it accept it it just accepts
the node and in here we're going to do
grammar items
I and within uh that thing we
are ooh we actually have to have a
nested Loop in here right we need to
have a nest Loop so let's go ahead and
freaking do that so it's going to be
size
t uh right so actually J let's not
forget uh grammar items I count you know
what I think it would be better to have
something like a grammar
branches uh
branches this
thing right and just take a point right
so we iterating um you know different
branches and this is the current
branches that we're itating so branches
count Plus+ J all right so and for this
thing we're going to be just printing it
like so um we actually need to print
node uh print uh branches uh
items J item within the item we have
either probability or node we not going
to print probability right now we're
going to print a little bit later so
we're just printing node then we're
going to be printing uh the separator
like so um and after that I suppose
we're going to print a new line so there
will be trading separator but we we can
take care of with a little bit later uh
we can actually take care of right now
so we're going to only print it if it's
if J is greater than zero right so yeah
so that's how we're going to go about it
um all right so does it compile let me
see it seems to be compiling so e is
never used but that's
fine so and in here let's do uh graph
grammar print so here is the grammar
that we're printing let's actually exit
with 69 right to sort of comment out all
the code down below look at that so emac
just highlighted this shed for for no
reason but whatever uh so here is the
grammar precisely the grammar that is in
a paper in here because here the first
thing is Rule two rule two rule two and
this is this one right so as you can see
C C C and C is that one down below then
we have random number or X or Y right
and here we go random number X or Y all
of that without any probabilities uh and
the last one is either rule one which is
this one so it's a rule one so add rule
two rule two uh so basically
self-referential thing uh and this is
multiplication also self- referential
thing so as you can see we managed to
Define it
properly
um anyways anyways anyways anyways so
how what's going to be the next thing
you could add a to alphabetic grammar
blah blah blah and waste a bunch of time
and not get anywhere I understand I know
that thank you so much all right so what
I want to do let's actually put the
probability just to see what the
probability is going to look like um
right so it's going to print F uh how we
going to put that so maybe I'm going to
put it in uh like a square bracket it's
yeah let's put it like this uh like it's
probably going to be huge uh
right um probability probability okay
let's go ahead and the probabilities are
rather big right so maybe I'm going to
simplify them like something like two or
maybe even
02 uh yeah something like this right so
here we are specifying the probabilities
um yep that's a it's a pretty good
grammar it's pretty good grammar all
right that's cool that's cool that's
cool that's cool that's
[Music]
cool we need to have now a fun a fun
that generates um a function a rendering
image function based on the grammar so I
don't really know how to call that but I
expect it to be node uh right so and
let's call it generate right and it
accepts the grammar uh grammar like
so um and obviously it probably will
return uh something like
this
um how should we call this function so
when we
do we have uh something called evolve
funk all right so and basically it just
like generates a function and stuff like
that um so let's do uh gen funk right so
this is going to be gen Funk and another
interesting thing in here is that yeah
so here is the actual algorithm by the
way right so it accepts uh right grammar
G and also initial rule that we're
generating and the depth um so actually
we're implementing this function so gen
Funk is this one because it accepts the
grammar G so here is the grammar G so we
also need to accept the initial rule so
I want to actually call it entry and
that's probably by the way why it is
called E because it's an entry right so
this is going to be entry and we're also
going to take the depth right so How
Deeply we can go into the
recursion um hello from SL Spain you're
from Spain I hope you're safe by the way
I heard a lot of news about Spain so I
hope you're uh staying safe safe out
there um right flooding is actually no
joke we had also flooding in like in
here in Russia like last year in summer
it was absolute disaster so I hope
you're staying safe
[Music]
um J fun probably is within next 30
years on the market I have no idea what
you're talking about but anyway right so
this is what we're doing and this is
what we are generating so the thing I
want to do now uh
is uh right so this is going to be basic
F gen Funk uh this is the grammar and
the entry is going to be e right so
because that's what it stands for and
the depth let's say is going to be
something like three so and afterwards I
kind of want to actually print uh the
note that we managed to generate in here
right I think it's going to be
interesting uh right so we generated
some things and now we're instantly
printing it okay so uh if I try to do
something in here uh right so all of
that is unused right now and so it's SEC
faed because it's actually null okay all
that is qued because it's actually no
that's
understandable oh boy oh boy oh boy oh
boy uh you know what I actually want to
make a small break uh right so I want to
make a cup of tea and after the break we
going to implement this function finally
right so this is the the main algorithm
maybe I can actually use this algorithm
exactly um but we'll see we'll see so
anyway uh let's make a small break I'm
going to make a cup of tea and we're
going to go back to that uh soon um okay
so let's go ahead and freaking do that
so we have grammar so we have an entry
that we're generating uh so first of all
I suppose we need to assert that the
entry is you know greater than zero
right so that's the first thing and uh
that it's less than the grammar uh count
right so that's one of the things we
want to make sure that it's within the
range uh because C is unsafe language so
we have to be careful with um you know
buffer overflows and stuff like
that um
okay so uh now uh we get
grammar items and this is the specific
entry uh and that gives us the grammar
branches
branches grammar and we're going to take
a point of this entire thing so I know
that they're supposed to have a certain
probabilities I just don't want to
bother with probabilities right now
so uh what I'm going to be doing is
um um I'm going
to grab one branch and just like try to
generate it so and I wonder how
difficult is it going to be so let's
actually do Rand mode uh branches um
count uh and that should give me a
random branch in here right so that
should give me a random
Branch uh but the count can be zero so
the count can be zero so what do we do
in case of a count being zero well that
means you Define grammar incorrectly you
D it dum dum uh so that is part of the
assert right so this is going to be
assert this thing is greater than zero
so that's kind of
important um right so here we grab
random thing so maybe we can do
something like a um index let's call it
Index right and there we go so it would
be better uh take um the probabilities
of branches into account right so I
acknowledge that this is something that
you need to do but I could not be asked
to do to do that right now I'm really
sorry about that so that gives us a
random branch and this is a random node
so that means by the way
that now we need to be generating based
on the uh node all right so here um we
are generating function based on the
entry within grammar based on the entry
within grammar but we need another one
that generates the function based on the
Noe which potentially may contain uh the
rules in stuff like that so it's going
to be actually um Mutual recursion right
so there will be two functions that
mutually recurse into each other if you
know what I'm talking about right so uh
it's going to be something like again uh
node grammar um right so and here
instead of Entry it is going to accept
the uh the node based on which it is
generating so it's also going to accept
the the depth right
um another interesting thing we need to
take the depth into account so if depth
is less or greater than zero that means
that is basically it and in that
specific case what exactly do we return
um I don't
know maybe this is not where we have to
be doing that maybe this is not where we
have to be doing that so maybe um yeah
is I think it has to
be it has to be when we call gen
Funk right and who calls gen Funk it's
gen node who's going to be calling G
Funk and it's gen node is going to check
the depth all right so that kind of
makes sense I
suppose uh so now let me actually see
let me actually see so now we we're
going to be actually switching upon
different kind right so we're speeching
upon different kinds know the kind uh
right so and let's
just these things are a bit annoying so
I put this white spaces just sort of
semantically separate different kinds of
node but it's not helpful because it
prevents me from copy pasting all of
that stuff like this uh all right so
let's eh it's hard uh I actually missed
typed some stuff uh let's put break in
here okay so if we just encounter one of
any of these
things right any of these nodes I feel
like we can just return them as
this or not really so for example things
that are just values x y and number they
can be right away returned as e um so
let's actually do it like that because
there's nothing to generate because they
bys generate themselves so the result of
that generation is just a no that's it
nothing to generate add multiplied
bullion by the way as well right Boolean
also generates
itself um things that have nested stuff
are more interesting by the way uh count
and K is the same as the default and it
is basically unreachable so if you
reached any of that stuff that means
you're probably iterating over corrupted
memories so uh that should fail right
away so things that have nested things
are rather interested so there's
different kinds of nested stuff uh for
example these are Bops right so these
are Bops and we can share some code with
them um so let me see how we can do that
so these are all bin Ops um node as bin
op and it has left hand side and we want
to do gen node grammar left hand side
depth do we go do we go do we increase
the depth I think for when the Gen node
calls itself that doesn't really
increase the depth right so we we're
going to only increase the depth when we
jump between different rules I think
that's going to be the the approach in
here so here's the left hand side right
so
LHS left hand side we do the same thing
for the right hand side uh right and now
we reconstruct back the the node in here
right so this is going to be
node um I can't just construct Bobs
unfortunately that's a bit
annoying so there's only the only thing
I can do is
node
yeah that is kind of annoying so what
I'm thinking what I'm thinking is
that we need a special thing for Bops
like literally
uh so there's a node lock and I think I
need to have something like node bin op
lock right so it accepts Char file int
line node kind kind and also LHS and rhs
right so LHS left hand side rhs right
hand side that's what they have so and
uh here we just create node lock file
line kind like so then we do as Bop LHS
it has to be like this and this is rhs
and we just return that like so and we
can Implement all of the uh Bobs in
terms of that and there's only four of
them if I'm not
mistaken so where are the bean
Ops gin node here they are so no add Mt
and mode so node add can be implemented
as
just
um oh here it is I can do it like that
node add is a
node Bop lock file
line um NK add like this and we can get
rid of this entire thing look at that uh
we can get rid of the multiplication now
because we can simply do add M boom
look at that so you see you see where
I'm going with all that you see I'm
going so it just makes it easier to
Define these kind of things uh right so
Mal mode boom uh
GT and every bin up is going to have
this kind of thing so it's not
applicable for things that have three
things like a triple or if uh but maybe
in the future we can actually
simplify how would they call trob right
so what's the operator like a Turner
turn up right the operator yeah turn
oper turn up uh like that so for example
if is a turn Operator Operator it has
condition than an else um right and the
the triple also turn operator damn so we
can actually compress a lot of stuff in
here actually uh surprisingly hm didn't
think about that
uh maybe it makes sense to align node in
here it didn't work so let's actually
align nodecore B There we go that
aligned it a little bit I can align it
even further I can align
LHS well that kind of works so let's
align LHS
comma
ooh that's annoying so I suppose this is
what we want to yeah there we go look at
that look at that look at that I would
like to maybe even get rid of some of
that stuff well I mean this is not how I
want you to align it so I guess I guess
I'll align it manually that's how I want
you to align look at that like at
that
um middle hand s yeah thank you so much
damis uh the seventh for for
Prime thank you thank you thank you um
so all right and that also allows me to
create Bops just by their kind right so
that's what it allows me to
do um by the way maybe it would make
sense for me to group all of the Bops
into like sequential thing and then
create begin Bops and end Bops uh yeah
so something like that would be actually
kind of cool so here is the X Y uh
random so those things they don't have
any arguments or anything like that rule
number are the things that have one AR
argument in there and it's usually value
Boolean also has one value so add mod GT
is that and it's that so what I'm
talking about in here is just something
like NK uh like begin uh bop
bop and this is end uh and
B something like that so then it's it's
easier for me to uh to distinguish the
ranges between them but I don't remember
like how can I make add uh to be equal
to to that like I I don't quite remember
how to use these things properly uh Bop
binary operator so that's what it stands
for because add multiply and mod GT are
binary operators Bobs so this ones
triples and ifs are going to be turn Ops
um it's actually a very common name I
think through among programming
languages uh like Bob and stuff like
that uh all right the reason why I
needed all of that stuff uh is now I
just want to be able to create create
node Bop Lo um so I have to pass node
file node line node kind LHS rhs so
that's that's why I needed this entire
stuff right so all of these things they
have like actual values uh all of these
things they are Bops triple and if
they're turn Ops in some sense um not
really sure like how approach
them I kind of have to approach them
separately uh but anyway so let me show
you what I'm meaning here so node
condition gen node grammar uh node as
triple so first uh first
depth uh just copy the old node and
change our CH probably I could do that
but I already created a new one so I
mean
I have 8 gigs of RAM so actually oh I
have 14 gigs of RAM so I think I think I
can
afford uh so anyways okay so here is
the condition so this is
condition uh then and this one is ah
it's not it's not that so it's actually
if right so this is applicable for if
triple is slightly different right
triple is slightly
different uh cond is
first uh
[Music]
second uh third and honestly introducing
something like
turnup would be very much beneficial
because it will enable me to reuse the
same code for triples and for ifs
because effectively there's the same
thing right they're just interpreted
differently by evaluators and stuff like
that uh right so yeah it would be nice
to somehow just reuse it's just like the
difference is this names and it's kind
of annoying uh it was if well I mean
like uh
yeah the compiler will tell us uh thank
you so we're generating this kind of
stuff and now we have to reorganize this
entire thing so node uh
triple well
I it's a wrong one Whatever A compiler
will tell me again Jesus doesn't matter
like don't don't do the compiler's
job um all right so
triple so this is the triple lock
node uh file node line uh first second
triple stat
one uh node triple it's actually if
block node file
node line con then
lse
them them all right so that is cool uh
so this things let's actually mark them
as to do ink rule I just want to see if
all that
compile so all of that is to do so does
it compile maybe for now I don't really
want to run this thing uh right so let's
just do
no right so what does it
say so first second
uh
third what am I
doing wait so there's the extra stuff in
here right so this stuff is not needed
because there's only three arguments in
again node right there's only three
arguments I actually over copy pasted
some stuff
that's
fine uh I just over copy pasted some
stuff uh triple doesn't like
something it's a third all right so this
is
third uh okay so entry comparison
between size T and some other stuff
maybe entry has to be size two okay so
that's fair let's keep it size two then
okay so branches count yeah so Arrow um
this is another arrow uh what else do we
have in
here um so for
now M so to do G
fun it's not finished what else do we
have in here it's unused this thing is
unused everything's fine okay all right
so this is how we generate the things
that don't really require any generation
so we're basically copying them right so
basically copying them um now when you
encounter rule this is where it becomes
interesting so when you encounter rule
you have to recursively call gen fun
because that's what you're generating
and maybe because of that this thing
should be called Rule and because of
that this things should be called Rule
okay so it's kind of interesting that
the proper naming comes to you as you
implement things right so sometimes if
you can't name a certain function
somehow just name it Whatever as you
implemented this function as the code
evolves the naming becomes more obvious
this actually happened to me many many
times right so it's just like if you
can't name a function certain way you
just don't have enough information the
way you got the information is by
actually implementing the function and
now you have more information now you
know how to cool this thing so this is
actually kind of cool so you generate
Rule and then you generate node and Rule
is a number within that makes a lot of
sense that's actually perfect okay
um so we're generating the rule uh and
in
here uh is just
that so in K rule uhhuh so we pass the
grammar then we take the node uh
interpret it as a rule and that's what
it is and the depth this is where we're
going to decrease the depth right this
is where we can decrypt the that and
this is another interesting thing is
that uh
yeah we probably don't want to go deeper
into into that generation
right because that's the question of
when do we stop right that's the
question of when do we
stop uh depth minus and we
probably
stop
mhm I don't really know yeah okay so
let's actually think about the stopping
condition a little bit later I still
haven't come up with a good stopping
condition
honestly um all right so we can think
about that later so random number now
random number is rather interesting it
should be relatively easy so just like a
node
um
mhm uh node
number but we're going to be using the
location of the random generator right
so it's a number lock uh file node
line and uh so let's introduce something
that I like to call random float Rand
float and it's a function that simply
generates a value random value from 0 to
one continuously right so it's a rent
float and then we're going to multiply
it by two right so since it's going to
be a range from 0 to one we multiplied
by two it becomes 0 to two and then we
subtract one uh out of that
right subtract one and that turns it
into a range from minus one to to one
right so that's that's what we're doing
here so rent float uh and that's about
the that's basically the generation of
this entire thing so let me see so it
complains about uh gen rule implicit
declaration that is understandable
actually so we need to forward declare
this entire thing here otherwise we
won't be able to do the what is it
called Mutual recursion Mutual
okay so we need to implement Rand float
uh right so how can we Implement that if
you take a look at the uh documentation
of function Rand what the is this
uh where is the
Rand three here it is so it's a
generates integer um with the max value
Rand
Max right its max value is Rand Max so
which you can do you can actually take a
Rand convert it to float divided by its
maximum value it can generate and you
got the value from 0 to one basically
that's how we can do that right so
because Rand by itself it's limited by
whatever random X is for that specific
lip C that you're
using um right and once you got like a
you know random float that is from 0 to
one it's basically like javascript's uh
math random right or random I don't
remember which one right so you can
multiply it by anything by any range and
there you go you scaling in that
specific range okay so um so that seems
to be Gucci all right what else do we
have in here so entry this thing is
called Rule uh right so this index is
unused uh and that is also called use
Rand so this is Rule what else do we
have in here it's unused it's unused
there was an error in here uh which I
don't understand undefined function gen
funk all right so this is yeah gen Rule
and yeah so we're generating rule entry
so with this kind of stuff and
everything seems to be working okay so
that's cool uh we have this kind of
thing mhm so take the probabilities of
branches into account so we for specific
rule right so for specific rule we are
generating the thing
[Music]
um so we need to do G
node uh let's
go so we pass the grammar that is
understandable uh then we pass the node
that we randomly picked and then we pass
the depth right and this is what we
effectively generate okay so as you can
see depth here is not really us really
well um right and unless we
are I really don't know when we are uh
you know subtracting the depth so this
one this algorithm is rather rather
interesting so it uses
only it's very abstract though right it
is very abstract though I don't think
it's very useful for us so we'll have to
come up with something something
else so for that specific rule like for
instance um what if I initially at the
very very top when I call uh G rule for
the first time I put depth zero that
means nothing is
generated right nothing is generated
nothing could be generated uh so that
means I have to return null so that
means gen rule May return null if
nothing is possible to
generate uh it may return n
um and that means it has to be taken
into account somehow uh okay so let's
actually go ahead and do something about
that um so for instance if depth is less
or equal than zero we just return n uh
so gen rule is not called anywhere
within this function but it is called in
here okay so what if this entire thing
returned null right so we could
generate any
further right so we accidentally we're
trying to generate a specific rule uh
but we simply simply couldn't right so
if it's equal to null what are we doing
here
um what exactly do we do in here I don't
freaking
know do we return some sort of like
empty
value uh or this algorithm is actually
kind of weird right so in case if we if
we can't go any further we should not
pick a
rule of in
itself
mhm that is bizar I didn't think about
that like how do you even do that how
did we do that in BNF fuzer uh let me
actually see so how uh because I already
already did that in BN fuzzer right so I
don't remember how do I stop the
recursion for some reason I'm struggling
to do that uh Generate random message
okay so here yeah so here is the bunch
of rules yeah so do we have any like a
depth in here we actually don't have
much depth limit the amount of Loops ha
so it's actually unlimited is that what
you're trying to tell
me wait a second like I just implemented
unlimited like I never really give a
right so there there's no
limitation in here on
depth what the
that's really funny
um so you need to separate terminal
rules and non-terminal rules yeah that's
probably something that would they have
to do uh but but they don't really do
that or I mean maybe they kind of imply
uh this kind of stuff so for example
when I'm generating this thing
um
and yeah they don't really talk about
terminals or maybe they do but I didn't
like you know read just a little bit uh
just you know on the surface level and
didn't read into that oh yeah they they
do actually okay so if a is a terminal
rule let a to go to step six return e
okay so and by the way in in our case
the terminal rules
are basically the the nodes
themselves basically the no themselves
so these are essentially terminal
rules right so
um this is a grammar this is a bunch of
rules initial rule so suppose a rule is
a sequence of basically nodes in their
probabilities if the depth is less than
zero then let a to be the first
a okay and go to step
four uhhuh then it goes to step four if
a is terminal rule go toep
six zity of
[Music]
n yeah don't don't really like any of
that stuff what if we just don't give a
about that so
I really don't want to deal with depth
right now so um so let's actually just
ignore depth
um and see what kind of complicated
rules it is going to gener because it's
going to stop eventually right so B
fuzer doesn't give a about rules
about depth and it terminates anyway at
some point so maybe maybe that's fine
right so let's actually try to see if uh
it compiles at all so here we just do
the rule uh um because because it kind
of makes it complicated right so like
how do we even stop right how do we even
stop all right seem to be compiling
right which is good and uh let's go
ahead and
simply Unleash the Power of random art
on this thing and it terminated by SE
fold that is very cool I'm I'm super
happy okay so let's actually go
and uh you know see in the in the
debuger in the debug wag how it's going
to look
like uh all right so this is what we
have I'm going to CD to that and GDB
random art run BT what do we have
oh well um
terminated by oh well I mean it it
corrupted the stack essentially uh nice
stack Overflow
nerded okay let me let me see let me
see we need to do the depth
depth deep all
right so uh generate the rule
and yeah
essentially um if
we like we can't know if some rule is
terminal or not if it's a very
complicated
expression we may not know right for
example this is a triple
but it's non-terminal because it
contains within its rules so that means
we need to have a function we need to
have a function that traverses the node
and makes sure that there's no enk rule
nodes anywhere in there and that's how
we know that it's a non- terminal
rule
so I guess this is what we have to do
like I don't see any other way to do
that seriously uh um right so let's
introduce something like node is
terminal um a looks like a list of
terminal rules yes it does but I mean so
so what so what like we can how does it
help us I don't understand so it
is a list of terminal rules but we are
working with a specific code in
a specific
implementation uh but doesn't C even
have a no whatever we need a function
that given a no code checks
whether it has an K rule or not and this
is how we can tell that a specific
branch is a terminal or non- terminal
right so okay it's cool that they
grouped it like that but I mean like we
talking about specific code
right so how do we do that with this
specific code uh anyways so we
take a node and we need to return
Boolean or not right so because the
expression may be rather complicated
right so just by looking at the
expression you can't tell whether it's a
terminal or not right if it refers to
some other nested rule or something like
it's not terminal obviously
obviously right so this a it might be
triple of A's which makes it kind DET
terminal I I don't know
[Music]
um yeah
so we need okay so here's the thing uh
we need a way to look at the node within
a branch at the expression within a
branch
and say for sure that it's going to be
terminating right and it's going to be
terminating is if within any of this
thing it doesn't contain any of the
rules or anything right so or maybe it
shouldn't be called terminal it's sort
of like a like a leaf or
whatever um so it's like a
leaf so what's
[Music]
funny that's annoying because the add
addition of probabilities makes it even
more complicated then
[Music]
the probabilities and we don't even
handle probabilities at all right so
here is the
entry right and I the only way I can
generate this specific entry is by
having depth at least two because I'll
have to go inside of it but what if I
set it to
one what do I generate in that specific
case it is a runtime error of some sort
right so that means the entire
generation process May
runtime error right so some depth are
simply not correct for certain grammars
and this is kind of like I didn't know
that it is
implied right I didn't think that it is
implied uh right so you can have a
grammar that requires a minimum depth at
least to generate something reasonable
right so that kind of makes sense I
guess right so you needed like a minimum
depth otherwise you you can't generate
anything
um
and so that means depth is kind of like
um arbitrary value not even arbitrary
value but kind of like non-strict value
it's kind of a recommended depth because
you not
necessarily can even able to comply with
that depth sometimes you know what I'm
saying right so right you have a certain
grammar and you have certain depth but
you you can't guarantee that that
grammar can't even comply with that
specific depth right so to generate
anything and that s in that case you
have to throw an error even because like
I don't know how to generate anything
with that shallow depth it's
impossible
um is a terminal
um it's it's a very annoying way of
doing things right I don't like this
make sure don't like that
I need to think I would like to maybe
make another break right so some sort of
another break
but it's kind of like this is a small
minor thing so this is a final detail
that I need to iron out and we're going
to have a proper system and I kind of
stuck with that like why am I stuck with
that I just the lack of creativity to to
to properly implement
it uh thank you so much for the sub uh
Gabrielle bazer
it should generate a terminal or not
based on the
depth uh for example if depth is one
then X Y or random number are
[Music]
generated
okay
uh should generate terminal or not based
on the
depth but I mean it's only for that
specific grammar what if I generate a
grammar that never like okay so
what if I have grammar that looks like
this generate me anything with that
grammar so it doesn't so you would say
it doesn't have terminal so that means
we have need to have a specific syntax
that takes into account terminal
rules so we uh semantically terminal
rules have to be marked
explicitly
uh techn the grammar shown in the paper
may never terminate exactly that's what
I'm talking about right
so like it's it's not like I don't
understand what needs to be done it's
just like the way it's all presented is
kind of
weird
right so what if I just remove this a
right how do I write algorithm now so
the algorithm should be smart enough to
analyze the grammar and tell oh okay so
here's the terminal rules and here's
non- terminal rules and stuff like that
so it has to be like very smart enough
to just tell this kind of thing um so
like it's weird what that's what I'm
saying it's not like I don't understand
like
if
whatever um just like it's presented in
a really weird way maybe I just missing
something maybe I just need to read it
carefully or whatever uh but
anyway um so one of the things we can
say is that no this terminal okay so
let's try to implement this function
that I wanted to implement whether not
is terminal or not um so let's switch
upon this
thing so it's going to be no the
kind determination of the rules is based
on probabilities have no idea
honestly um why do I again have these
spaces didn't I remove them I think I
think I eded them
again uh all right
so so the thing that I don't like is
that it's described on a too high of a
level it is too high of a level of
description uh which says oh just you
know stop at ter terminal rules but to
determine what is a terminal rule you
need to write a whole ass
algorithm and everything how it's it's
implied just just like it's too high
level just stop somewhere when depth
is you know what I'm saying it's just
like that's what annoys me it's just
like it's too high it's just like a
terminal stop it some point you
[Music]
know right it's just like and now I'm
the one who have to implement all of
that like what is a terminal okay
so does it contain rule does it go
anywhere just like what what is that um
so that that's what's annoying
doesn't make sense
right okay so X Y random so the only
thing that
we uh right
uh we need to do some stuff in here so
Random rule so all of that stuff so X is
definitely terminal right Y is
definitely terminal uh we might even
just put them like this right so
number uh right so that
thing
um so it will eventually end with all
the C nodes are sold with the a node
exactly exactly but how do we know that
we have to end with a nodes how do we
know that we have to end with a noes how
do we know
that
well so we have to analyze we have to
analyze the nodes we have to just see
you
know that's what I'm talking about
that's what I'm talking about so node uh
as Bob as Bob like it's it's very easy
to say oh just end with with a no but
I'm the one who have to write this
stupid algorithm
you know I'm the one who has to copy
paste and make this switch case it's
easy to say oh just write this
thing so come on come on guys come
on that's what I'm
saying okay so if this thing is um
terminal so I suppose it's it's when
both of
them uh return
this thing is terminal and this thing is
terminal so
rhs okay so and I suppose this is the
same for this stuff this stuff this
stuff right so we get that and for
triples it's also the same kind of
[Music]
thing so
Z you don't understand just end
everything on a Zin just end everything
on a it's that easy just just do
that come on it's not that hard just do
that okay
um so
else
um what are you type in some stupid text
there just stand it on on on a stand it
on
a uh third okay so um what is this thing
this terminal and stuff like
that so had could result to get Prett
yeah maybe that's what they did in that
paper I don't know so Random is
kind of like honestly random is in fact
terminal in some regard even though it's
a rule thingy it is a
terminal um it is terminal doesn't go
any further right rule on the other hand
that is instantly false this is what I'm
talking about like we need to analyze
this stupid tree uh right to just see if
it contains the rule anywhere that's
what I was talking about as soon as we
can see that node okay it contains rule
maybe I should actually qu it node uh
contains uh contains rule right
uh contains
rule uh and in that case it actually
changes everything so it's actually
called uh terminal it it kind of inverts
that is terminal uh
right uh so here's ink and this is the
default uh right and now unreachable and
what's that it's the no this
terminal
so yeah and that will allow us to say
that for inance this thing doesn't go
any further and this thing doesn't go
any further this thing doesn't go any
further we can even uh now say that the
rule is terminal by answering that each
individual branch in here is terminal
with this function and all of that is
magically implied and that's why I'm
annoyed like
that right all of this recursive stuff
is just somehow magically
implied just do that I mean come on this
is
so all right so this is is
terminal okay so
um
yeah
now here's the
thing here is the thing
it means we can go a bit
further so when
I'm so when I'm generating this
thing and depth is already zero the
depth is already zero
I need to pick the node which is an
expression that is going to
terminate uh according to my definition
is terminal none of these thing will
terminate because they contain rule so
that means I'll have to be kind of
forced to go to any of those
things
um so but then maybe I can introduce the
definition of a terminal rule
which accepts grammar and Rule index and
answer the question whether that rule is
terminal by checking all of its nodes to
be
terminal um that's one of the things we
can
do that's very interesting so in
essentially um yeah when we are
generating a rule it has a bunch of
branches uh it has a bunch of branches
and I look which branch is a terminal
and I just straight up go there just
straight up go into the terminal one
that's how te problem apply
here we're kind of trying to solve a
halting problem don't we um so
yeah uh we're kind of trying to solve a
halting problem so we just go there uh
if we don't have any of the terminating
branches we just have to pick the random
one
or um
okay so take probabilities into account
blah blah
blah uh so
if depth is greater than one we just do
something like this
all right and also minus one
whatever if depth is less or equal we're
trying to find the first one that is
terminal right so I'm going to iterate
through all the branches in here
branches uh count Plus+ sign so here's
branches count Plus+ sign node is
terminal so it accepts only in the node
right so yeah it accepts only the node
so it's going be branches
items index node if this thing is
terminal right I
simply uh
just generate that thing right
away ahuh so this is index I might as
well actually call this thing index
because it makes it kind of
easy right just return this stuff like
so huh if we did didn't find any of
them we just pick
whatever again because we don't really
have a
choice uh so which kind of implies that
maybe we can do the following thing if
depth is greater or equal to zero right
greater equal to zero that's what we do
in
here and then we just let it fall
through like that
this is very weird and annoying way of
doing that so that means we may have
depth that is already well below
somewhere uh but since we haven't found
any of the termination nodes uh we kind
of keep going so we're not guaranteed to
terminate honestly to to be
fair uh but maybe we we are we we maybe
we kind of are we'll eventually go
somewhere that that will terminate but
it's just all really weird that's that's
what I'm saying it's just all really
weird um so triple con did you mean ah
yeah
it's I I confuse those things again
me first uh second so I'm actually kind
of annoyed at this problem I'm really
kind of annoyed I didn't expect that
this is such an annoying weird problem
um
con
yeah it's it's still s fault and it's
probably still going
on um further and
further depth less orle is reversed
isn't it depth less or
equal
no no
no depth less or equal me means that we
need to stop so we're iterating through
all of these annoying branches and see
which one will give us the
Stop and if we couldn't find anything
okay let's go to the random one who who
tried to debate me who tried to debate
me um
anyway uh
so so what if I just put zero in here
will it ever stop uh
okay it doesn't even stop okay so maybe
maybe I'm just doing something correctly
I don't
know uh run BT yeah it's still going
forever it's cannot access the memory
yeah so because it's just it's still
going forever this is such an annoying
problem um
[Music]
so
yeah doesn't know is it still picking
all three nodes in C instead of first
one so we
are decreasing depth right so gen
node we passing the depth
alone with all of the terminal ones
right so we're passing the depth alone
in here so then we do the Gen Rule and
within the
rule
MH so it's still picking all three nodes
no it shouldn't well I mean yeah it's
still picking all three noes but
hopefully it
should we need to encourage it to go to
the terminal
rule we can introduce a notion of the
terminal rule which is kind of a weird
thing to
do okay so we have a node that is
terminal then we can look at the rules
that are terminal right so which one is
the terminal
[Music]
rule um does node is terminal well I
mean it does otherwise we would have see
it in a stack
Trace node rule should not return
constant fals I think
why what are you why are you people
debating me what are you talking about
right
so once you should stop don't ever
choose a terminal node you already have
used in this
stack what are you all talking about
none of your messages make any sense
within the context of what I'm trying to
achieve um
CH go away
um so you only distracting me
[Music]
um that is no okay we are making a break
we're making a break this is
annoying problem I hate it all right so
here's the idea we come up with let's
actually allow the generator to not
generate anything at all if it if it
failed to do do so so let's just let it
wander around within the depth that we
tell it to wander around right and if we
go lower lower particular depth we just
return null and the random generator
that picks random branches right if it
observes that something was not properly
generated it will simply try
again with a different branch like try
again with a different branch okay it
failed try again and we can actually
have a like a limited number of retries
so the whole process may not generate
anything because it couldn't find any
terminated State and let's assume that
is fine because I could not be bothered
to make anything more robust neither do
the authors of these papers I
suppose maybe I I don't know like I
didn't fully read it but from what I
read that's the only option we have
anyway so
let's give it a
try so uh essentially if uh depth is
less or equal than zero uh we just
return null so that means gen rule U May
return uh null so and that also means by
the way that uh node so this is a node
is terminal so we don't care whether
it's terminal or not anymore right so we
can get rid of that idea this thing may
also return n uh depth less or equal
than zero return n let's actually
include uh these kind of things into the
depth or maybe not I don't know I
actually don't know maybe the depth is
incremented when we uh jump to like we
when we try to resolve a rule I think
that make kind of makes sense yeah that
kind of makes sense so if we encounter
these things we terminate if we
encounter this thing this one is
interesting so now since gen node May
return n because rule May return n right
um so that means we have to do if not
LHS return
no for all of them by the way if not
rhs return
no yeah that's that's what we have to do
if not first return
no
second uh
third C
then else can your wi do that can your
do that
Fu so
sorry
uh what do we need what else do we need
I think that's basically it so every
time we do a rule we just do minus one
in here and this is where it's going to
basically check all of that okay look at
that sh
friend look at that so um here's that we
take a random thing in here and we
generate a random
node right and if node is equal to know
we should try again furthermore we can
do something like while and do do
while let's just do the
while um
yeah so and this is where we're going to
have several attempts right so we can
have uh like
attempts maybe
zero maybe zero
um so attempt +
one
H uh I actually got a very interesting
idea so
[Music]
and attempts uh less than gen
rule Max
attempts
uhhuh so this is the first
attempt then we can just Define how many
attempts we want to
have uh let's say we're going to have
three attempts maybe 10 attempts I don't
Fu know let's give it a
try uh so is there do four Loop maybe
there is I don't
know um
okay maybe we can also make the amount
of attempts part of the Gen
rle why
not we can try to do something like that
all right so if f um if not F we can do
something
like um the crappy generation process
didn't
find U okay could not
terminate and then we just do return
one so stupid I swear to
God uh all right so here's the oh oh
oh all right so got this
thing um I wonder if I can do some
like
four um
attempts and
note equal to n um
and attempt
like this plus
attempt is that a good
Loop right so while node is equal to n
attempts less than that we increment
that so we don't have to do that um yeah
and it's actually single index so we
might as well just inline this thing to
make it more intimidating and there we
go then we just return look at that look
at that look that that's
[Music]
po I really like that so that allows us
to have multiple
attempts uh yep the craid generation
process couldn't
terminate I wonder if I'm just doing
something incorrectly all right so how
many attempts we have uh attempt okay so
what what about 100
attempts that is am I doing
something something should have
terminated so it it okay so you quote
cat you said that you it will never
terminate if you change example
um okay so just a second uh if you
change example to
ca uh it's more likely to terminate ah
we yeah so for it to likely to terminate
we probably have to take into account
the probabilities so that's that's the
thing we have to
do all right let's try to take into
account the probabilities
uh shall
we okay it's not shouldn't be that hard
I
think uh shouldn't be that hard so how
we how we do that we can actually so if
the probabilities end up like add up to
one right we can kind of assume that
they add up to one in here they must add
up to one um so this on this is
68 uh right so I can't really visualize
that in my head but
68 do they yeah they do add up to one so
that makes sense so we just assume that
they add up to one so that means we can
generate a value from 0 to one so which
is the probability like this so and
essentially each individual probability
right so
zero to
one uh we can assign a certain sub range
of that probability right so we can say
that this size of the probability okay
it's that Branch this is that branch and
this is another Branch so we have three
branches with different probabilities
and they have different segments within
like value 0 to one right and since
we're heting a random place within the
range of 0 to one we're heating
different segments of it with different
probabilities this smaller segment has
less probability of being hit than the
bigger one
so and that's how we generate different
branches with different probabilities at
least that's how I understand it so uh
and essentially after we generated a
random Branch we need to iterate them
and see within which range we actually
hit this thing uh right so let's
actually do I uh less than the amount of
branches right so something like
that
mhm and uh all right so
and we need to keep track of that
specific probability right so this is
zero right so what we do we just add the
probability of the current Branch so
this is going to
be this thing and this is I right so we
add the probability and as soon as T
became greater or equal to that P that
we generated that means that's the thing
we want to generate in here um uh right
so this is going to be I and we're
generating it in here uh and we're
breaking out of the loop right so we're
essentially breaking out of the loop so
that kind of includes uh the
probabilities
probability right is that reasonable way
of doing that chat what do you think is
that a reasonable way to do
that I think it is
[Music]
so that's how I usually do
that
um re knows
best yes but you can still have error
yeah with yeah yeah 0333 because we
probably want to do some uh fractions
and stuff like that so if we hit like
too much outside if if this Loop just
terminates without ever picking anything
in here this is basically a failed
generation so that means we're going to
attempt another another
one
so well we can do that we can yeah so
essentially if it fails like we're going
to try again on another attempt uh
another one another one
um
so all right so the probability so yeah
since this has a higher probability that
will very likely to
terminate
um unused attempts ah all
right so somebody suggested to actually
make uh
half all right so what let's actually
make it
half
uh and this one is was fourth right okay
so this one is fourth
uh this one is fourth so let's actually
put
commas
everywhere this makes me think what if I
made mistake anywhere in the generation
process did I make any maybe okay so
let's actually let it do
five holy it generated something
two
days two days of
work implementing a crappy white paper
resulted in us generating this thing
holy
uh so um what I want you to do I
think I want you to initialize the
seed God seed
all right so yeah let's actually do a
bigger depth
hopefully okay so finally we have
something more
interesting okay now we're
talking all right thank you so much guys
for for helping me all right so because
yeah so just using the original ones
it's it's a mess uh we can try to use
the original probability
so I I suppose probabilities are very
important right so this one no I guess I
just need to give it like a deeper I
just needed to let it go
deeper
deeper so let's go ahead and now try to
render some pixels with this thing
right uh so now we should be able to
render some
pixels so no triple and this is just F
right okay let's go okay so here is the
function right and we generated some
image with this function how does it
look
like this is how it looks like so it's a
random image generated with this
specific
function um so it would be kind of nice
if we could save this specific function
and provide it as the uh as argument
uh probably needs normalization from
minus one to one space but we already
implemented didn't we uh so like this is
already solved problem what are you
talking
about um H what's
what's we literally implemented it
yesterday why are you bringing up the
soloft problem excuse me let's double
check uh where is the generate image or
or is it render image render pixels so
so what is this
then what is this if excuse me here is
the here's the normalization and stuff
stuff like
that we're taking that in account
serialize it to Bean file and do some
weird wizard casting stuff when opening
it it's not going to work right so we
can't we don't have uh we don't have a
way to do
that because they're all over the place
right so they just allocated you know
sequentially and that means I need to
save Arena it's it's a pain in yes I'm
going to be doing it um all right let's
generate more images I suppose uh right
so here's another image right so let's
take a look at
it we don't even have signs or Co signs
but
um
it's is it not continuious it it is
continuious in memory but we're being
very careless in terms of how we we we
don't allocate it in a very careful
manner we just splatter it all over the
place without thinking too much um so
it's just like I didn't prepare a
separate array of nodes and didn't
locate there so we have some garbage
nodes for instance that are not needed
anymore so and it's just all within this
single memory pool so taking that memory
pool that contains a lot of garbage and
dumping it into the file system like why
we could do that that and it will
probably work but it's nasty it's nasty
if this is a hack that I would only
employ if I had no choice if I just
needed to ship something
quickly like okay but I'm I'm doing
Recreation program I don't need to ship
anything quickly right so like no uh it
would be better if we had a Passa right
so that allows us to parse this kind of
expressions from text so we can like
copypaste these things safe to a file
and then make a script that reads that
file and puts it back into this random
art and generates random arts and stuff
like that that would have been
cool right and maybe Implement something
similar to BNF fuzzer where I could
provide the grammar right it generates a
random function based on that grammar
and then the image out of that function
that will be even cooler I think
so uh yeah so as you can see we can do
different things and these images are
kind of cool actually uh right so here's
another
image we're generating random R
this one is
cool this one is cool like where does it
come from right
so yeah that's so awesome uh
right um Let me let me see so can we
increase the depth what about 20 uh what
if I make it 20 okay that okay so we
generated this expression this huge ass
expression uh and let's take a look at
how the output is going to look
like this is so awesome uh let
me try Okay this was so worth it
I okay I didn't expect that spending
time on this stuff would be so worth it
like what the uh okay so here is
another one so this is a bit okay this
one's kind of boring uh right so here's
the big expression so it's spending some
time actually rendering that expression
right so yeah so it needs to evaluate
this on each pixel right so that's why
it takes a little bit of time of doing
that but maybe it's going to worth it
that is so
cool
right that is
insane holy it would be kind of
cool if we like really had an access to
their expression uh so what they managed
to they generated these kind of things
for instance
um right
so wish they could share their grammar
um but
anyway we we so what if we make it
deeper let's make it even deeper okay so
that that's a big one right emac didn't
even show the entirety of it uh maybe I
can okay so that's the entirety of the
expression uh it is rendering it so this
is the expression we're trying to render
right now I don't know if it will be
able to do that uh terminated by
kill did we ran out of memory I don't
fck why why was it
killed so when it usually killed when it
ran out of memory or
something uh nice so nerd thank you
let's give it a try one more
time uh
right there are some examples in here
okay oh it's a AR ah it's the yeah I
know what you're talking about it's
these things that were referenced by the
paper okay so we are actually running
out of memory unfortunately to to even
render some
stuff
uhuh it's taking too much time I'm sorry
okay so let's do 25 and a b so maybe
this one is not going to be that
bad
honestly um I think we just need to
clean up the memory after evaluation or
something or just a second when we are
are evaluating right so do
we we do allocate shed ton of memory
while evaluating wait a second here's
the thing we can do so arena. do we have
have a reset of the
Arena uh we probably don't have an
ability
to take snapshots yeah we don't have an
ability to take snapshots and I don't
really want to implement it right now
but anyway so I think this is a very
complicated way of implementing this
kind of thing um as I already said it
would have been much easier if this if
the function was not really a but a
neural network wouldn't
be right so we can try to do that right
so I have ann. H uh right ann. H can we
just generate like a random neural
network and plug that neural network
into render image because we already did
that right so we basically already did
that um so would it generate more
interesting images maybe I don't
freaking know so so I I need to remember
how to use this entire thing so just a
second all right so let's actually grab
this stuff uh
row
um and it's easier because you don't
have to mess with grammars then ests and
everything you just generate a bunch of
matrices and you're done with it right
so you don't have to do any of that
stuff uh let me do W get uh and I'm
going to just you know take that stuff
uh let's open random art random art. C
and I'm going to Simply include uh an
N.H uh so I think nn. H yeah it also has
implementation right so here the
implementation thing uh but I forgot how
to use that does anybody remember how to
use an
in um right so there's some examples in
here uh that we created so third party
Min demos uhuh so image to NN yeah yeah
boy so I need to find the main entry
that's that's a lot of stuff
okay o we actually have separate yeah we
have like arenas for this kind of
stu um all
right so where is okay so here is the
neural
network yeah so we are allocating neural
network uh by providing an
architecture right so this is how we
allocate in the neural
network so let me put that stuff in here
and
architecture uh architecture Arc is an
array which describes the sizes of the
layers right so here's the first thing
is the amount of input neurons right so
and the last one is the demount output
neurons and all of these sizes are
basically the sizes of the layers right
so this is like a classical uh
perceptron multi-layer perceptron
MLP uh so we can put this stuff in here
maybe right so uh and do we specify the
size of the arch yeah so we use array
length so the input here is going to be
two MLP mentioned yeah so little Point
uh and this one is going to be three
right so two is X and Y right
essentially X and Y and this one is just
uh RGB so let's actually not make it
super big but maybe this architecture is
fine uh right so we do n then uh a lock
right and if I'm not mistaken n just
means that you allocate it on a heap
right so here you can specify the region
within which you want to allocate but
yeah so it has its own Arena
stuff uh afterwards we usually uh
randomize it which is generate a random
thing so so we just allocate a bunch of
so this is for the images it doesn't
really matter uh yeah so we randomize
from minus one we already using minus
one to one would you look at that okay
so we just randomized the neural network
uh so all of the weights and biases are
you know minus one to
one okay that's pretty cool uh and uh
yeah so how do we forward so essentially
we can
create uh render pixels all right render
pixels and it accepts f as you can see
so let's create a version that actually
accepts Ann uh right so it's going to
accept Ann like this it's a very
lightweight object if I'm not mistaken
uh right
so yeah it's it's a bunch of numbers
right all of these things are basically
pointers nothing particularly special
and um yeah so when we evaluating these
things we actually just just forwarding
some stuff and then
forward um aha okay that's actually
super cool so what you have to
do you have to find the
input let me
see there was a way to have an input met
or maybe and then yeah there you go so
by doing Ann input you get sort of like
a matrix or row yeah you get a matrix
that is input yeah it's actually row
look at that uh so this is the row so
that means uh what you can
do you can just say
that mhm so this is the zero is going to
be n x and one is going to be n y all
right so you take an input for the
neural network so this is the first
neuron and this is the second neuron
afterwards you forward that neural
network so that will forward this value
and then you can basically take the
output of the neural
network uh right so NN
output NN right
zero 1 2 not really because it's a row
right so row um what's the definition of
row it has elements right so it has
elements uh which means what I have to
do is more like
elements right and in here as
well see see you see
so basically the input is a specific row
within uh within neural network right so
you take that row you can assign certain
values in there then you forward that
just propagates all of these
values uh right is this random art
project on GitHub not yet I'm going to
publish it on GitHub I'm going to
publish the right so we forward it and
then we get these values out of the
outputs right so that's what we do
essentially in
here uh might as
well
honestly do it like this so it's easier
for me than to extract this things so C
so let's actually copy paste it in here
right and then I can say that this one
is
CR uh
GB right and these
things emx emx shut the up
emx emx shut the up so it will make
it super easy for me to just switch
between this stuff right
um so and and back and forth so maybe
we're going to have this as a like you
know compile time thing here all right
so if I try to rebuild this entire thing
it's going to complain um so array
length
redefined oh so array length is
defined with an NH and this is why by
the way I can do now unde array length
in here right as you can see I can uh
strip the prefixes right but then some
libraries start to conflict with that
and I can undev that AR length so this
is not going to be a conflict anymore
right so I really thought about it for
quite some time how to properly do that
uh conflicted time with the region oh
it conflicts with the region in the
arena well an arena does not actually
allow to
damn why didn't I prefix
arena
with why didn't they call Arena region
what the is wrong with me okay so
cre replace
region uh
region region
okay all
right
um
mhm I'll probably have to
then submit that as a pull well I mean
it's my reper I don't have to submit the
PO request but you get the point uh all
right so what else do we have in here
Rand
float it comes from uh nn. h nn.
damn I should actually prefix uh do a
similar thing with prefix in for and end
H so rent flat is already implemented in
here okay I see it's already there time
well it wants to have time let's give it
time what else do you want for me uh
yeah so in here uh in here what we want
to do we want to actually pass an
N all right so what we need to do by the
way we don't really need to generate but
I mean it still generates stuff
uh it generated output and how the
output looks like looks like
nothing
well it just look looks very
gray uh yep and I think I know
why um I think I know why
because it's not guaranteed to even
return values from minus one to
one when you are developing a grammar
you can kind of guarantee that this
value are going to be from minus one to
one you kind of have more control over
that is the output range minus two to
one I don't know like that that's the
thing so like it's difficult to control
the range in here it's kind of difficult
to control the range so it can be
like overflow or underflow very easily
all right so I suppose random grammar
generation kind of won it kind of won uh
right so with neural networks I need to
think a little bit more how to do that
but I think like idea with neural
networks might be actually feasible
maybe to some extent I don't know so
let's go back to random art without any
neural network Shenanigans uh right so
let's go here and here uh right so and
let's just do it like
that
so okay let's take a look at what it's
going to generate is it going to
generate some cool art uh is it going to
generate some cool fart it gener cre
some cool fart uh look at that isn't
that a cool fart that's the coolest fart
I've ever seen in my entire life right
mid Journey get the out of here
it's not only cooler than mid Journey
it's also absolutely ethical
because it doesn't use any copyrighted
material D D D D get him get him M
Journey get him uh so okay um I'm going
to just you know clean up the source
code and then publish it on GitHub for
everyone and then um essentially the the
two streams the two days are going to be
concatenated into a single vode and
uploaded to YouTube so it's going to Big
single vode and all all of the materials
all of the links all of the source code
is going to be in the description so
thank you everyone who subscribed and
stuff like that so let me acknowledge
the subs uh thank you so much NX def
chat is cute chat is cute in I do agree
with that uh so Valen Gabriella deis
thank you thank you thank you really
appreciate all of the subs so that was a
cool session actually two days session
it was a little bit of frustrating so we
had a little bit of a frustration with
the grammar and stuff like that uh right
but we managed to overcome that right
because we're real software Engineers
we're not afraid of problems we Face the
problems right so uh the only thing we
need is just a cup of tea that's it
all right that's it for today thanks
everyone who's watching me right now I
really appreciate that have a good one
and I see you all on the next Recreation
programming session with a