trueagi-io / hyperon-experimental

MeTTa programming language implementation
https://metta-lang.dev
MIT License
140 stars 46 forks source link

Referential transparency on non-deterministic functions #700

Open AnnelineD opened 4 months ago

AnnelineD commented 4 months ago

Describe the bug Non-deterministic functions are not referentially transparent.

To Reproduce

> !(subtraction (superpose (a b d)) (intersection (superpose (a b c)) (superpose (a b d))))
[d]
> (= (test6 $set $subset) (subtraction $subset (intersection $set $subset)))
> !(test6 (superpose (a b c)) (superpose (a b d)))
[b, d, a, d, a, b, d]

Expected behavior The wrapped function test6 produces the same result as the top-level test.

Actual behavior test6 gets applied element-wise.

Additional context

vsbogd commented 1 month ago

The issue is that test6 is not typed and thus its arguments are evaluated before function call. Thus test6 is called in the pairs. First item of the pair is an element of the (a b c), second item is an element of the (a b d). It works according semantics of the non-determinism in MeTTa. One can make work this example by adding type for the test6:

(: test6 (-> Atom Atom Atom))
(= (test6 $set $subset) (subtraction $subset (intersection $set $subset)))
!(test6 (superpose (a b c)) (superpose (a b d)))
[d]