emulate a lambda

39 views
Skip to first unread message

Chris Smith

unread,
Sep 27, 2021, 11:13:04 PM9/27/21
to sympy

I would like to emulate something like this with Basic objects. I am drawing a blank on how that might be done. Does anyone have any ideas?

>>> f=lambda x: x==1 
>>> f(1) 
True 
>>> Lambda(x, f(x))(1) # doesn't work 
False

/c

Oscar Benjamin

unread,
Sep 28, 2021, 2:42:27 AM9/28/21
to sympy
Something like this:

In [7]: cat w.py
class SymbolicEquality:
    def __init__(self, sym):
        self.sym = sym
    def __eq__(self, other):
        return Equality(self.sym, other)

In [8]: f = lambda x: x == 1

In [9]: y = Dummy('y')

In [10]: F = Lambda(y, f(SymbolicEquality(y)))

In [11]: F
Out[11]: y ↦ y = 1

--
Oscar

Aaron Meurer

unread,
Sep 28, 2021, 5:22:06 AM9/28/21
to sympy
Why not just Lambda(x, Eq(x, 1))?

I don't think redefining __eq__ to return a symbolic result is a good
idea. You're liable to get a lot of "TypeError: cannot determine truth
value of Relational" errors from using that object.

Aaron Meurer
> --
> You received this message because you are subscribed to the Google Groups "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/CAHVvXxQO%3DOoH%2BVwTPm%2BLSOZ5GpE9ipyHUad1xB_xivJ8iff2aA%40mail.gmail.com.

Oscar Benjamin

unread,
Sep 28, 2021, 2:38:05 PM9/28/21
to sympy
On Tue, 28 Sept 2021 at 10:22, Aaron Meurer <asme...@gmail.com> wrote:
Why not just Lambda(x, Eq(x, 1))?

I don't think redefining __eq__ to return a symbolic result is a good
idea. You're liable to get a lot of "TypeError: cannot determine truth
value of Relational" errors from using that object.

There is a missing context for the question in this thread:
https://github.com/sympy/sympy/pull/22152#discussion_r716898734

The OracleGate class has a non-Basic lambda function in its args:

In [3]: from sympy.physics.quantum.grover import OracleGate

In [4]: e = OracleGate(1, lambda x: x == 2)

In [5]: e.args
Out[5]: (1, <function __main__.<lambda>(x)>)

The question was how you could sympify such a lambda function to Basic:

--
Oscar

Aaron Meurer

unread,
Sep 28, 2021, 4:16:26 PM9/28/21
to sympy
I think we can store a Lambda in the args, similar to ImageSet.
Alternatively if the lambda always only has 1 argument we could store
OracleGate(1, x, Eq(x, 2)). (I'm having a little hard time
understanding exactly what should be allowed for the second arg of
OracleGate).

Aaron Meurer
> --
> You received this message because you are subscribed to the Google Groups "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/CAHVvXxQ_SJA2S8Oc6Rmiu9Z3CBs5WnhnnePsvp-HcN11_0x1Jg%40mail.gmail.com.

Chris Smith

unread,
Sep 29, 2021, 10:19:24 PM9/29/21
to sympy
The problem is that this returns an Eq instead of False when it is not equal:
```
>>> f = lambda x: x == 1
>>> F = Lambda(x, f(SymbolicEquality(x)))
>>> F(1)
True
>>> F(x)
Eq(x, 1)
>>> f(x)
False
```

Aaron Meurer

unread,
Sep 30, 2021, 4:02:47 PM9/30/21
to sympy
So it sounds like OracleGate needs the function to not be symbolic at
all. You can use the following to create a symbolic function that
evaluates as a given lambda:

>>> f = Function('f', eval=lambda x: x == 1)
>>> f(1)
True
>>> f(0)
False

Aaron Meurer
> --
> You received this message because you are subscribed to the Google Groups "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/13d15197-0d82-4312-b94a-ec59df616aedn%40googlegroups.com.

Aaron Meurer

unread,
Sep 30, 2021, 4:08:10 PM9/30/21
to sympy
Although storing f in the .args of an expression would be just as
problematic as storing a lambda, because functions are not objects. So
you might need to make a custom evaluator class similar to Lambda that
stores a given lambda on it. It's a little messy because it breaks
with the SymPy pattern that objects should only store symbolic data.

Aaron Meurer

Oscar Benjamin

unread,
Sep 30, 2021, 4:13:15 PM9/30/21
to sympy
I don't know what the OracleGate class is for but I'm pretty sure it's not very useful and it's certainly poorly designed. I'd rather just delete it than try to come up with hacks to make it work.

If someone wants to maintain the quantum module then that's great. Until then we shouldn't allow broken code like this to complicate the maintained part of the codebase.

Oscar

Chris Smith

unread,
Sep 30, 2021, 6:12:21 PM9/30/21
to sympy

Aaron Meurer

unread,
Sep 30, 2021, 6:24:53 PM9/30/21
to sympy
My understanding is that an OracleGate is just the quantum version of
Function. It probably should just be Function (maybe a subclass that
mixes Function and Gate), with users creating oracles by subclassing
and defining eval.

Aaron Meurer
> To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/eae0a8a1-2742-4d06-9581-3f0804ebe06cn%40googlegroups.com.

Aaron Meurer

unread,
Sep 30, 2021, 6:28:14 PM9/30/21
to sympy
It is relevant to think about how we might do this in other ways,
though, because if we ever want to make Functions themselves Basic
objects we would need to refactor them in a similar way
(https://github.com/sympy/sympy/issues/4787). In fact, if Functions
were objects, we could just store the function object on the
QuantumGate args.

Aaron Meurer

thepauli...@gmail.com

unread,
Jan 22, 2022, 9:49:46 AM1/22/22
to sympy

I proposed a solution in this PR https://github.com/sympy/sympy/pull/22887 which stores the (lambda) function in a wrapper class subclassing from Atom, thus circumventing storing any non-Basic in args.
Reply all
Reply to author
Forward
0 new messages