Comments (17)
This is solved by sealing the arguments in respective scopes, which would split $y in the final reduction step (disallowing non-local unification, but also enabling the individual reductions).
from metta-examples.
Actually I think it does work! But the code should be
(= ((λ $x $f) $y) (let ($νx $νf) (alpha-convert ($x $f)) (let $νx $y $νf)))
i.e. no need to alpha-convert $y
.
from metta-examples.
There may be a workaround with a drawname grounded function that gives you a fresh variable to use in the beta reduction.
from metta-examples.
@ngeiswei , thanks for raising it again. We already had a workaround for this in old Rust interpreter thus your code will work correctly with minimal MeTTa disabled. In minimal MeTTa let
is implemented using unify
thus this issue raises again. But I think we need to implement a long term solution this time.
I like your suggestion:
Actually I think it does work! But the code should be
(= ((λ $x $f) $y) (let ($νx $νf) (alpha-convert ($x $f)) (let $νx $y $νf)))
i.e. no need to alpha-convert
$y
.
It should work exactly as previous let
workaround, but adding alpha-convert
allows us introducing scoping in any context we need it. I will try adding quick implementation to check whether it works as expected.
from metta-examples.
(= ((λ $x $f) $y) (let $x $y $f))) !((seal (, $x) (λ $x ($x $x))) ((seal (, $y) (λ $y ($y $y)))) (let $x (λ $y1 ($y1 $y1)) ($x $x)) ((λ $y ($y $y)) (λ $y1 ($y1 $y1))) (let $y (λ $y1 ($y1 $y1)) ($y $y)) ...
Basically
(seal (, v1 v2 ... vn) <body>)
says "when you're evaluating body,vk
will not be accessible outside of " i.e. it makes the variables anonymous.
In hyperon-experimental all variables inside λ
are anonymous already. One can say each call has body variables sealed. Thus in fact ((λ $y ($y $y)) (λ $y ($y $y)))
is unified with (= ((λ $x#1 $f#1) $y#1) (let $x#1 $y#1 $f#1))
. But after unification we have { $y == $x#1 }
and finally we have (let $y (λ $y ($y $y)) ($y $y))
.
But we could use sealing inside let
I believe in a way which is suggested by @ngeiswei:
(= ((λ $x $f) $y) (let ($νx $νf) (seal (, $x) ($x $f)) (let $νx $y $νf)))
from metta-examples.
@ngeiswei it should work in a following form on the branch from trueagi-io/hyperon-experimental#609
Wow, I confirm that it solves the problem on my end.
from metta-examples.
There may be a workaround with a drawname grounded function that gives you a fresh variable to use in the beta reduction.
Right! So I suppose you mean something like
(= ((λ $x $f) $y) (let ($νx $νy $νf) (alpha-convert ($x $y $f)) (let $νx $νy $νf)))
That's a great suggestion, although I feel we may still want to consider adding a built-in scope or sealing (if there's a difference).
from metta-examples.
Oh, actually that doesn't work either in my test case :-(, maybe you meant something else...
from metta-examples.
@Adam-Vandervorst, would you mind showing how the solution using seal
would look like?
from metta-examples.
(= ((λ $x $f) $y) (let $x $y $f)))
!((seal (, $x) (λ $x ($x $x))) ((seal (, $y) (λ $y ($y $y))))
(let $x (λ $y1 ($y1 $y1)) ($x $x))
((λ $y ($y $y)) (λ $y1 ($y1 $y1)))
(let $y (λ $y1 ($y1 $y1)) ($y $y))
...
Basically (seal (, v1 v2 ... vn) <body>)
says "when you're evaluating body, vk
will not be accessible outside of " i.e. it makes the variables anonymous.
from metta-examples.
The English is the desired requirement for seal, yes!
from metta-examples.
I see... You've automatically alpha-converted $y
to $y1
to avoid name collision but it's not super clear how. I suppose what you meant was more something like
((seal (, $x) (λ $x ($x $x))) ((seal (, $y) (λ $y ($y $y))))
rewrites into
(seal (, $x) (let $x (seal (, $y) (λ $y ($y $y))) ($x $x)))
which rewrites into (note how the outer (seal (, $x) ...)
will disappear since $x
no longer appears in the body),
((seal (, $y) (λ $y ($y $y))) (seal (, $y) (λ $y ($y $y))))
which is OK because $y
of the first mockingbird operator is sealed from the $y
of the second one. If we keep going we get
(seal (, $y) (let $y (seal (, $y) (λ $y ($y $y))) ($y $y)))
Then MeTTa needs to unify $y
with (seal (, $y) (λ $y ($y $y)))
which it can because $y
in the right term is sealed.
But I wonder how is seal
different than a regular scope?
from metta-examples.
It indeed works with the old MeTTa. @vsbogd, could briefly explain why? What is the workaround in question?
Ah, you've already answered that above.
from metta-examples.
@ngeiswei it should work in a following form on the branch from trueagi-io/hyperon-experimental#609:
(= ((λ $x $f) $y) (let ($νx $νf) (sealed ($x) ($x $f)) (let $νx $y $νf)))
from metta-examples.
We can implement it as sealed
which generates random variable names and replaces variables or as alpha-conversion
+ new-var
which decouples generating var and variable renaming. I am not sure what is the best option.
from metta-examples.
I don't know either. Somewhat perhaps related, after reading @leithaus Transparent MeTTa proposals, I wonder if we wouldn't want to replace variables by a quotation construct @
which would allow to give variables structure. That way alpha-conversion
could be implemented in pure MeTTa. There are other use cases, for instance I wanted to have two types of variables in the backward chainer, one for program holes, one for program variables (like in Idris, ?x is a hole while x is a variable).
If we don't want to depart from $
as variable indicator, then $
could simply be used on expressions such as $(x y)
, etc.
from metta-examples.
SICP and combinator logic examples also suffer from this. Possible fix which uses non-merged seal is in my private branch https://github.com/vsbogd/metta-examples/tree/minimal-seal-patch
from metta-examples.
Related Issues (11)
- Missing explanations on how to run Child AI HOT 1
- in child_ai.py hard to understand the curiosity_behavior function
- Canonical way to process and/or present complex expressions with nested subexpressions HOT 4
- Question regarding types and their understanding HOT 3
- Question regarding performance hacks HOT 6
- Recursion with multiple matches HOT 3
- Case as replacement for cond HOT 7
- Could (if) return True instead of its content? HOT 5
- What is the canonical way to write queries to knowledge graph HOT 44
- Slow list creation HOT 8
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from metta-examples.