acton icon indicating copy to clipboard operation
acton copied to clipboard

Codegen for Times[ZZ] does not output zQ_TimesD_ZZG_new function

Open mzagozen opened this issue 1 year ago • 6 comments

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 avatar Jan 08 '25 21:01 mzagozen

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.)

sydow avatar Feb 27 '25 11:02 sydow

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.)

nordlander avatar Feb 27 '25 12:02 nordlander

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

plajjan avatar Feb 28 '25 20:02 plajjan

This is a dupe of #1126.

plajjan avatar Jul 18 '25 20:07 plajjan

@nordlander what is the big remaining problem? :)

plajjan avatar Jul 18 '25 20:07 plajjan

@plajjan See my comment in #2380

nordlander avatar Jul 19 '25 20:07 nordlander