Let function / segfault

If you're having trouble using Context Free or don't understand the language, ask for help here.

Moderators: MtnViewJohn, chris, mtnviewmark

Post Reply
sicivsibro
Posts: 7
Joined: Mon Aug 20, 2012 12:21 pm

Let function / segfault

Post by sicivsibro »

With the latest hg source, this segfaults:

Code: Select all

testf(number a1, number b1) = if(a1==b1,5,10)
shape test
rule{
  CIRCLE []
  CIRCLE[x let(n=5..10;m=testf(n,2);1,m) a -0.5 sat 1 b 1 y 5 h 90]
}
And I can't figure out how to use let in a function, or define local function variables:

Code: Select all

testf(number a1, number b1) = let(c=a1*b1;c)
shape test
rule{
  CIRCLE []
  CIRCLE[x testf(1,2)]
}

Code: Select all

Error in test.cfdg at line 2 - Arguments are expected.                            
Error in test.cfdg at line 4 - Definition with same name as user function                            
Error in test.cfdg at line 4 -     user function definition is here.
I also just found out about vector2 (after expanding the complex kissing circles formula) Is there a function that extracts individual terms from vectors?

User avatar
MtnViewJohn
Site Admin
Posts: 882
Joined: Fri May 06, 2005 2:26 pm
Location: Mountain View, California
Contact:

Re: Let function / segfault

Post by MtnViewJohn »

sicivsibro wrote:With the latest hg source, this segfaults:

Code: Select all

testf(number a1, number b1) = if(a1==b1,5,10)
shape test
rule{
  CIRCLE []
  CIRCLE[x let(n=5..10;m=testf(n,2);1,m) a -0.5 sat 1 b 1 y 5 h 90]
}
Yes, that is a bug. I see no problem with your code. I wonder what you are doing with 1,m as your let expression. This makes let() return a vector2. Giving a vector2 to the x adjustment is equivalent to setting x and y. But then you adjust y later on.

Also, 5..10 returns a real number in the interval [5,10). The odds of this being exactly equal to some integer is extremely small. Maybe you intend to use the randint() function?
sicivsibro wrote: And I can't figure out how to use let in a function, or define local function variables:

Code: Select all

testf(number a1, number b1) = let(c=a1*b1;c)
shape test
rule{
  CIRCLE []
  CIRCLE[x testf(1,2)]
}

Code: Select all

Error in test.cfdg at line 2 - Arguments are expected.                            
Error in test.cfdg at line 4 - Definition with same name as user function                            
Error in test.cfdg at line 4 -     user function definition is here.
Again, there is something going on with let(). Your code should work. But why have let() at all in this case? You could just have:

Code: Select all

testf(a1, b1) = a1*b1
sicivsibro wrote:
I also just found out about vector2 (after expanding the complex kissing circles formula) Is there a function that extracts individual terms from vectors?
Gah! I forgot to document the vector extraction operator! a1[0] extracts the 1st element of the vector2 a1 and a1[1] extracts the 2nd element.

sicivsibro
Posts: 7
Joined: Mon Aug 20, 2012 12:21 pm

Re: Let function / segfault

Post by sicivsibro »

That was just example/test code while I was fiddling, trying to get let to work. The actual function is:

Code: Select all

dtcrn(a1,b1,k1,a2,b2,k2,a3,b3,k3,k4) =
  let(  p1r   = k1*a1 + k2*a2 + k3*a3;
        p1i   = k1*b1 + k2*b2 + k3*b3;
        p2r   = k1*k2*a1*a2 - k1*k2*b1*b2 + k2*k3*a2*a3 - k2*k3*b2*b3 + k1*k3*a1*a3 - k1*k3*b1*b3;
        p2i   = k1*k2*a1*b2 + k1*k2*a2*b1 + k2*k3*a2*b3 + k2*k3*a3*b2 + k1*k3*a1*b3 + k1*k3*a3*b1;
        p3r   = sqrt(sqrt((p2r^2) + (p2i^2)))*cos(atan2(p2i/p2r)/2);
        p3i   = sqrt(sqrt((p2r^2) + (p2i^2)))*sin(atan2(p2i/p2r)/2);
        p4rp  = (p1r + 2*p3r)/k4;
        p4rn  = (p1r - 2*p3r)/k4;
        p4ip  = (p1i + 2*p3i)/k4;
        p4in  = (p1i - 2*p3i)/k4;
        p4rn)
a1[0] extracts the 1st element of the vector2 a1 and a1[1] extracts the 2nd element.
Great! I'll probably use vectors now to represent the complex numbers; this will make life a lot easier. Most likely I'll end with many more functions Cadd, Cmul, Csub, Csqrt, etc.

I wrote some example code to get a feel of the vector* parameter types:

Code: Select all

CF::Background = [b 1]
startshape tests() []

test_vector_parameter2(vector2 a1) = a1[0]
test_vector_parameter3(vector3 a1) = a1[1]
test_vector_parameter4(vector4 a1) = a1[2]

vector2 test_vector_return2(number a1, number b1) = (a1,b1)
vector3 test_vector_return3(number a1, number b1, number c1) = (a1,b1,c1)

shape tests
rule {
  CIRCLE [hue 200 sat 1 b 1]

  // test vector parameters
  CIRCLE [ x test_vector_parameter2((3,-3)) hue 50 sat 0.5 b 0.5]
  CIRCLE [ x test_vector_parameter3((3,-3,5)) hue 250 sat 0.5 b 0.5]
  CIRCLE [ x test_vector_parameter4((3,-3,5,0)) hue 300 sat 0.5 b 0.5]

  // test vector return
  CIRCLE [ x test_vector_return2(2,4) hue 25 sat 0.75 b 0.75]
  CIRCLE [ x test_vector_return3(-2,4,-3) hue 300 sat 0.75 b 0.75]
  CIRCLE [ x (test_vector_return3(-4,6,-5)[0]) hue 300 sat 0.75 b 0.75]
}
It all works fine, except the last CIRCLE entry is a syntax error:

Code: Select all

Error in test.cfdg at line 23 - syntax error                            
Is it not allowed to use vector extraction operator inside a shape adjustment list?

sicivsibro
Posts: 7
Joined: Mon Aug 20, 2012 12:21 pm

Re: Let function / segfault

Post by sicivsibro »

I haven't been able to declare vector variables:

Code: Select all

test_vector_parameter3(vector3 a1) = a1[1]

shape tests
rule {
  vector = (10,20,3)
  CIRCLE [s 0.5 x vector]
  r1 = test_vector_parameter3(vector)
}

Code: Select all

Error in test.vector.cfdg at line 25 - This argument should be a vector                            
Error in test.vector.cfdg at line 5 - This is the expected type.
There is some weird behavior in the above too, the circle is shifted by (x,y)->(10,3), as though the vector variable were actually a vector, except it ignores the middle term.

in the meantime, my workaround is to define vector* construction functions:

Code: Select all

vector2 test_vector_return2(number a1, number b1) = (a1,b1)
vector2 vector2(number a1, number b1) = (a1,b1)

shape tests
rule {
  vector = vector2(10,20)
  CIRCLE [s 0.5 x vector]
  r1 = test_vector_parameter2(vector)
}

sicivsibro
Posts: 7
Joined: Mon Aug 20, 2012 12:21 pm

Re: Let function / segfault

Post by sicivsibro »

I'm running into some computational problems, and I think it is a problem with CFDG, but it is difficult to debug - could use some sort of print statement. In any case the following math computes correctly in python:

Code: Select all

vector2 vector2(number a1, number b1) = (a1,b1)
vector3 vector3(number a1, number b1, number c1) = (a1,b1,c1)

vector2 Cadd(vector2 c1, vector2 c2) =
  (c1[0]+c2[0],c1[1]+c2[1])

vector2 Csub(vector2 c1, vector2 c2) =
  (c1[0]-c2[0],c1[1]-c2[1])

vector2 Cmul(vector2 c1, vector2 c2) =
  (((c1[0]*c2[0])-(c1[1]*c2[1])),((c1[0]*c2[1])+(c1[1]*c2[0])))

number Cmulconj(vector2 c1) =
  (c1[0])^2 + (c1[1])^2

vector2 Cmulnum(vector2 c1, number n1) =
  (c1[0]*n1,c1[1]*n1)

vector2 Cconj(vector2 c1) =
  (c1[0],-c1[1])

vector2 Cdivnum(vector2 c1, number n1) =
  (c1[0]/n1,c1[1]/n1)

vector2 Cdiv(vector2 c1, vector2 c2) =
  Cdivnum(Cmul(c1,Cconj(c2)),Cmulconj(c2))

vector2 Csqrt(vector2 c1) =
  (sqrt(sqrt(c1[0]^2 + c1[1]^2)) * cos(atan2(c1[1],c1[0])/2),
   sqrt(sqrt(c1[0]^2 + c1[1]^2)) * sin(atan2(c1[1],c1[0])/2))

// Descartes' theorem of mutually tangent circles, negative and positive
dtn(k1,k2,k3) = k1 + k2 + k3 - 2*sqrt(k1*k2 + k2*k3 + k1*k3)
dtp(k1,k2,k3) = k1 + k2 + k3 - 2*sqrt(k1*k2 + k2*k3 + k1*k3)

// complex version
vector2 dtcn(vector2 c1, number k1, vector2 c2, number k2, vector2 c3, number k3, number k4) =
  Cdivnum(
    Csub(Cadd(Cadd(Cmulnum(c1,k1),Cmulnum(c2,k2)),Cmulnum(c3,k3)),Cmulnum(Csqrt(
      Cadd(Cadd(Cmulnum(Cmul(c1,c2),k1*k2),Cmulnum(Cmul(c2,c3),k2*k3)),Cmulnum(Cmul(c1,c3),k1*k3))),2)),k4)

vector2 dtcp(vector2 c1, number k1, vector2 c2, number k2, vector2 c3, number k3, number k4) =
  Cdivnum(
    Cadd(Cadd(Cadd(Cmulnum(c1,k1),Cmulnum(c2,k2)),Cmulnum(c3,k3)),Cmulnum(Csqrt(
      Cadd(Cadd(Cmulnum(Cmul(c1,c2),k1*k2),Cmulnum(Cmul(c2,c3),k2*k3)),Cmulnum(Cmul(c1,c3),k1*k3))),2)),k4)

shape ApollonianGasket
rule{
  r1  = 1/2
  k1  = 1/r1
  c1  = vector2(0,0)
  r2  = 1/2
  k2  = 1/r2
  c2  = vector2(1,0)
  r3  = 1/2
  k3  = 1/r3
  c3  = vector2(1/2,sqrt(3)/2)
  CIRCLE [x c1 s (2*r1)]
  CIRCLE [x c2 s (2*r2)]
  CIRCLE [x c3 s (2*r3)]
  k4  = dtn(k1,k2,k3)
  r4  = abs(1/k4)
  c4  = dtcn(c1,k1,c2,k2,c3,k3,k4)
  // the error
  CIRCLE [x c4 s (2*r4)]
  // no error, proper translation
  //CIRCLE [x 0.5 y (sqrt(3)/6) s (2*r4)]
}

Code: Select all

A shape got too big.                            
A shape got too big.                            

User avatar
MtnViewJohn
Site Admin
Posts: 882
Joined: Fri May 06, 2005 2:26 pm
Location: Mountain View, California
Contact:

Re: Let function / segfault

Post by MtnViewJohn »

The dtcn() function is returning a NaN. I will figure out where it is coming from.

User avatar
MtnViewJohn
Site Admin
Posts: 882
Joined: Fri May 06, 2005 2:26 pm
Location: Mountain View, California
Contact:

Re: Let function / segfault

Post by MtnViewJohn »

I misspoke when I called it a vector extraction operator. It can only be used with a vector variable, not with an expression that returns a vector.

I fixed Context Free such that your Apollonian Gasket code works. I would like to send you a developer build so that you can try it and shake out more bugs. Which OS do you use?

sicivsibro
Posts: 7
Joined: Mon Aug 20, 2012 12:21 pm

Re: Let function / segfault

Post by sicivsibro »

Thanks, thats awesome: linux, but I prefer to compile from source (https://code.google.com/p/context-free/), so you need only send a patchset.

User avatar
MtnViewJohn
Site Admin
Posts: 882
Joined: Fri May 06, 2005 2:26 pm
Location: Mountain View, California
Contact:

Re: Let function / segfault

Post by MtnViewJohn »

I just pushed all the changes up to https://code.google.com/p/context-free/

sicivsibro
Posts: 7
Joined: Mon Aug 20, 2012 12:21 pm

Re: Let function / segfault

Post by sicivsibro »

Overview
  • segfault: fixed
  • let: fixed
  • vector variables: enabled/fixed
  • weird vector/shape adjustment behavior: fixed
  • vector function return: fixed
Overall: all fixed. Thanks!

One slight difference with latest ContextFree is that all functions default to the natural type, instead of number, generating these errors:

Code: Select all

Mismatch between declared natural and defined not-natural type of user function
Fixed by a change like:

Code: Select all

type_error(number a1, number b1) = 5.5
number type_working_number(number a1, number b1) = 5.5
type_working_natural(number a1, number b1) = 5.0

User avatar
MtnViewJohn
Site Admin
Posts: 882
Joined: Fri May 06, 2005 2:26 pm
Location: Mountain View, California
Contact:

Re: Let function / segfault

Post by MtnViewJohn »

I can't reproduce this on Mac or Ubuntu. Can you paste in the entire cfdg file, not just a snippet?

Post Reply