Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Codegen for Times[ZZ] does not output zQ_TimesD_ZZG_new function #2061

Open
mzagozen opened this issue Jan 8, 2025 · 3 comments
Open

Codegen for Times[ZZ] does not output zQ_TimesD_ZZG_new function #2061

mzagozen opened this issue Jan 8, 2025 · 3 comments
Labels
bug Something isn't working

Comments

@mzagozen
Copy link
Collaborator

mzagozen commented Jan 8, 2025

Acton Version

0.24.1.20250108.8.28.39

Steps to Reproduce and Observed Behavior

I wanted to implement the Times[ZZ] protocol to allow multiplication of ZZ.

import testing

class ZZ(value):
    re: float
    im: float

    def __init__(self, re, im):
        self.re = re
        self.im = im

    def __str__(self):
        if self.re == 0 and self.im == 0:
            return "0"
        elif self.re == 0:
            return "%fj" % self.im
        elif self.im == 0:
            return str(self.re)
        else:
            return "%f + %fj" % (self.re, self.im)

    def __repr__(self):
        return "ZZ(%f, %f)" % (self.re, self.im)

extension ZZ(Eq):
    def __eq__(self, other):
        return self.re == other.re and self.im == other.im

extension ZZ(Plus):
    def __add__(self, other):
        return ZZ(self.re + other.re, self.im + other.im)

    @staticmethod
    def __zero__():
        return ZZ(0, 0)

extension ZZ(Times[ZZ]):
    def __mul__(self, other: ZZ) -> ZZ:
        return ZZ(self.re * other.re - self.im * other.im,
                  self.re * other.im + self.im * other.re)

def _testZZ():
    c0 = ZZ(0, 0)
    c1 = c0 + ZZ(1, 0)
    c11 = c0 + ZZ(1, 1)    
    testing.assertEqual(c0, ZZ(0, 0))
    testing.assertEqual(c0 + c0, ZZ(0, 0))
    testing.assertEqual(c1, ZZ(1, 0))
    testing.assertEqual(c11, ZZ(1, 1))
    testing.assertEqual(c1 * c1, ZZ(1, 0))

It looks like the generated C code is missing the zQ_TimesD_ZZG_new function?

❯ acton test
Building project tests...
Failed to build project tests
actonc exited with code 1 / 0
stderr: Building project in /home/mzagozen/aoc/2024
  Compiling z.act for development
   Finished compilation in   0.097 s
  Compiling tf2.act for development
   Already up to date, in    0.000 s
  Compiling tf.act for development
   Already up to date, in    0.000 s
  Compiling d02.act for development
   Already up to date, in    0.000 s
  Compiling d01.act for development
   Already up to date, in    0.000 s
  Compiling aoc.act for development
   Already up to date, in    0.000 s
  Compiling d03.act for development
   Already up to date, in    0.000 s
  Compiling d04.act for development
   Already up to date, in    0.000 s
  Compiling d05.act for development
   Already up to date, in    0.000 s
  Compiling d06.act for development
   Already up to date, in    0.000 s
  Final compilation step
ERROR: internal compiler error: compilation of generated Zig code failed, returned error code1
NOTE: this is likely a bug in actonc, please report this at:
NOTE: https://github.com/actonlang/acton/issues/new?template=ice.yaml
NOTE: acton 0.24.1.20250108.8.28.39 compiled by ghc 9.6 on linux x86_64
NOTE: cc: 0.13.0
zig stdout:

zig stderr:
Acton Project Builder - building /home/mzagozen/aoc/2024
Acton Base Builder
Building in /usr/lib/acton/base
-- filename : uri.c
   full_path: /usr/lib/acton/base/out/types/uri.c
   dir      : /usr/lib/acton/base/out/types
   file_path: /uri.c
-- filename : base64.c
   full_path: /usr/lib/acton/base/out/types/base64.c
   dir      : /usr/lib/acton/base/out/types
   file_path: /base64.c
-- filename : re.c
   full_path: /usr/lib/acton/base/out/types/re.c
   dir      : /usr/lib/acton/base/out/types
   file_path: /re.c
-- filename : numpy.c
   full_path: /usr/lib/acton/base/out/types/numpy.c
   dir      : /usr/lib/acton/base/out/types
   file_path: /numpy.c
-- filename : md5.c
   full_path: /usr/lib/acton/base/out/types/crypto/hash/md5.c
   dir      : /usr/lib/acton/base/out/types/crypto/hash
   file_path: /crypto/hash/md5.c
-- filename : process.c
   full_path: /usr/lib/acton/base/out/types/process.c
   dir      : /usr/lib/acton/base/out/types
   file_path: /process.c
-- filename : snappy.c
   full_path: /usr/lib/acton/base/out/types/snappy.c
   dir      : /usr/lib/acton/base/out/types
   file_path: /snappy.c
-- filename : file.c
   full_path: /usr/lib/acton/base/out/types/file.c
   dir      : /usr/lib/acton/base/out/types
   file_path: /file.c
-- filename : xml.c
   full_path: /usr/lib/acton/base/out/types/xml.c
   dir      : /usr/lib/acton/base/out/types
   file_path: /xml.c
-- filename : rts.c
   full_path: /usr/lib/acton/base/out/types/acton/rts.c
   dir      : /usr/lib/acton/base/out/types/acton
   file_path: /acton/rts.c
-- filename : term.c
   full_path: /usr/lib/acton/base/out/types/term.c
   dir      : /usr/lib/acton/base/out/types
   file_path: /term.c
-- filename : json.c
   full_path: /usr/lib/acton/base/out/types/json.c
   dir      : /usr/lib/acton/base/out/types
   file_path: /json.c
-- filename : time.c
   full_path: /usr/lib/acton/base/out/types/time.c
   dir      : /usr/lib/acton/base/out/types
   file_path: /time.c
-- filename : random.c
   full_path: /usr/lib/acton/base/out/types/random.c
   dir      : /usr/lib/acton/base/out/types
   file_path: /random.c
-- filename : testing.c
   full_path: /usr/lib/acton/base/out/types/testing.c
   dir      : /usr/lib/acton/base/out/types
   file_path: /testing.c
-- filename : argparse.c
   full_path: /usr/lib/acton/base/out/types/argparse.c
   dir      : /usr/lib/acton/base/out/types
   file_path: /argparse.c
-- filename : buildy.c
   full_path: /usr/lib/acton/base/out/types/buildy.c
   dir      : /usr/lib/acton/base/out/types
   file_path: /buildy.c
-- filename : __builtin__.c
   full_path: /usr/lib/acton/base/out/types/__builtin__.c
   dir      : /usr/lib/acton/base/out/types
   file_path: /__builtin__.c
-- filename : logging.c
   full_path: /usr/lib/acton/base/out/types/logging.c
   dir      : /usr/lib/acton/base/out/types
   file_path: /logging.c
-- filename : net.c
   full_path: /usr/lib/acton/base/out/types/net.c
   dir      : /usr/lib/acton/base/out/types
   file_path: /net.c
-- filename : http.c
   full_path: /usr/lib/acton/base/out/types/http.c
   dir      : /usr/lib/acton/base/out/types
   file_path: /http.c
-- filename : math.c
   full_path: /usr/lib/acton/base/out/types/math.c
   dir      : /usr/lib/acton/base/out/types
   file_path: /math.c
Debug build
Threads enabled
Debug build
Threads enabled
Threads enabled
Building executable from: /home/mzagozen/aoc/2024/out/types/z.test_root.c -> .test_z
Building executable from: /home/mzagozen/aoc/2024/out/types/tf2.test_root.c -> .test_tf2
Building executable from: /home/mzagozen/aoc/2024/out/types/d05.test_root.c -> .test_d05
Building executable from: /home/mzagozen/aoc/2024/out/types/d06.test_root.c -> .test_d06
install
+- install .test_d05
   +- zig build-exe .test_d05 Debug x86_64-linux-gnu.2.27
      +- zig build-lib ActonProject Debug x86_64-linux-gnu.2.27 5 errors
/home/mzagozen/aoc/2024/out/types/z.c:12:31: error: equality comparison with extraneous parentheses
/home/mzagozen/aoc/2024/out/types/z.c:12:31: note: remove extraneous parentheses around the comparison to silence this warning
/home/mzagozen/aoc/2024/out/types/z.c:12:31: note: use '=' to turn this equality comparison into an assignment
/home/mzagozen/aoc/2024/out/types/z.c:16:31: error: equality comparison with extraneous parentheses
/home/mzagozen/aoc/2024/out/types/z.c:16:31: note: remove extraneous parentheses around the comparison to silence this warning
/home/mzagozen/aoc/2024/out/types/z.c:16:31: note: use '=' to turn this equality comparison into an assignment
/home/mzagozen/aoc/2024/out/types/z.c:137:31: error: call to undeclared function 'zQ_TimesD_ZZG_new'; ISO C99 and later do not support implicit function declarations
/home/mzagozen/aoc/2024/out/types/z.c:137:22: error: cast to 'B_Times' (aka 'struct B_Times *') from smaller integer type 'int'
/home/mzagozen/aoc/2024/out/types/z.c:257:36: error: comparison of distinct pointer types ('B_NoneType (*)(zQ___test_main)' (aka 'struct B_NoneType *(*)(struct zQ___test_main *)') and 'B_NoneType (*)($Actor)' (aka 'struct B_NoneType *(*)(struct $Actor *)'))
error: the following command failed with 5 compilation errors:
/usr/lib/acton/zig/zig build-lib -cflags -ffile-prefix-map=/home/mzagozen/aoc/= -DDEV -DACTON_THREADS -- /home/mzagozen/aoc/2024/out/types/d01.c -cflags -ffile-prefix-map=/home/mzagozen/aoc/= -DDEV -DACTON_THREADS -- /home/mzagozen/aoc/2024/out/types/d03.c -cflags -ffile-prefix-map=/home/mzagozen/aoc/= -DDEV -DACTON_THREADS -- /home/mzagozen/aoc/2024/out/types/d06.c -cflags -ffile-prefix-map=/home/mzagozen/aoc/= -DDEV -DACTON_THREADS -- /home/mzagozen/aoc/2024/out/types/z.c -cflags -ffile-prefix-map=/home/mzagozen/aoc/= -DDEV -DACTON_THREADS -- /home/mzagozen/aoc/2024/out/types/aoc.c -cflags -ffile-prefix-map=/home/mzagozen/aoc/= -DDEV -DACTON_THREADS -- /home/mzagozen/aoc/2024/out/types/d02.c -cflags -ffile-prefix-map=/home/mzagozen/aoc/= -DDEV -DACTON_THREADS -- /home/mzagozen/aoc/2024/out/types/d04.c -cflags -ffile-prefix-map=/home/mzagozen/aoc/= -DDEV -DACTON_THREADS -- /home/mzagozen/aoc/2024/out/types/tf.c -cflags -ffile-prefix-map=/home/mzagozen/aoc/= -DDEV -DACTON_THREADS -- /home/mzagozen/aoc/2024/out/types/d05.c -cflags -ffile-prefix-map=/home/mzagozen/aoc/= -DDEV -DACTON_THREADS -- /home/mzagozen/aoc/2024/out/types/tf2.c -ODebug -target x86_64-linux-gnu.2.27 -mcpu westmere -I /home/mzagozen/aoc/2024 -I /home/mzagozen/.cache/acton/zig-local-cache/o/5ba49e2ea7f7137e8db6df131fec41ff -Mroot -lc++ -lc --cache-dir /home/mzagozen/.cache/acton/zig-local-cache --global-cache-dir /home/mzagozen/.cache/acton/zig-global-cache --name ActonProject -static --listen=- 
Build Summary: 36/47 steps succeeded; 1 failed (disable with --summary none)
install transitive failure
+- install ActonProject transitive failure
|  +- zig build-lib ActonProject Debug x86_64-linux-gnu.2.27 5 errors
+- install .test_z transitive failure
|  +- zig build-exe .test_z Debug x86_64-linux-gnu.2.27 transitive failure
|     +- zig build-lib ActonProject Debug x86_64-linux-gnu.2.27 (+2 more reused dependencies)
+- install .test_tf2 transitive failure
|  +- zig build-exe .test_tf2 Debug x86_64-linux-gnu.2.27 transitive failure
|     +- zig build-lib ActonProject Debug x86_64-linux-gnu.2.27 (+2 more reused dependencies)
+- install .test_d05 transitive failure
|  +- zig build-exe .test_d05 Debug x86_64-linux-gnu.2.27 transitive failure
|     +- zig build-lib ActonProject Debug x86_64-linux-gnu.2.27 (+2 more reused dependencies)
+- install .test_d06 transitive failure
   +- zig build-exe .test_d06 Debug x86_64-linux-gnu.2.27 transitive failure
      +- zig build-lib ActonProject Debug x86_64-linux-gnu.2.27 (+2 more reused dependencies)
error: the following build command failed with exit code 1:
/home/mzagozen/.cache/acton/zig-local-cache/o/caeea20549f1656dc477d219b371f57a/build /usr/lib/acton/zig/zig /home/mzagozen/aoc/2024 /home/mzagozen/.cache/acton/zig-local-cache /home/mzagozen/.cache/acton/zig-global-cache --seed 0x523d5669 -Z31dffbeade203dbe --prefix /home/mzagozen/aoc/2024/out --prefix-exe-dir bin -Dtarget=x86_64-linux-gnu.2.27 -Dcpu=westmere -Doptimize=Debug

Expected Behavior

The program compiles and ZZ multiplication works!

@mzagozen mzagozen added the bug Something isn't working label Jan 8, 2025
@sydow
Copy link
Collaborator

sydow commented Feb 27, 2025

I looked at this. The problem is that the compiler considers that the implementation of Times[ZZ] misses the Plus methods (Times is a subprotocol of Plus). So if you reorder the Acton source to merge these two extensions everything works:

extension ZZ(Times[ZZ]):
    def __add__(self, other):
        return ZZ(self.re + other.re, self.im + other.im)

    @staticmethod
    def __zero__():
        return ZZ(0, 0)

    def __mul__(self, other: ZZ) -> ZZ:
        return ZZ(self.re * other.re - self.im * other.im,
                  self.re * other.im + self.im * other.re)

Whether this is a temporary problem to be fixed (there are some remaining problems with extensions) or not, I will have to ask the live language definition @nordlander.

(More exactly, the problem is in CodeGen.hs, function declCon, where the compiler decides that the witness class has two abstract attributes add and zero and hence does not generate a new function.)

@nordlander
Copy link
Contributor

This example should indeed work as expected without modifying the sources. But the example is also a good illustration of the big remaining problem with extensions, which I'm telling myself I must return to shortly. (The small remaining problem is that we can't implicitly declare extensions by simply listing protocol ancestors when a class is defined, but I guess that's easier to live with.)

@plajjan
Copy link
Contributor

plajjan commented Feb 28, 2025

I don't understand what the big problem with extension is? You only explained the / a small problem

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants