forked from trueagi-io/hyperon-experimental
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathf1_imports.metta
130 lines (113 loc) · 5.01 KB
/
f1_imports.metta
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
; NOTE: This test won't work under no python mode because it relies on
; specific atoms in the space. When running in Python, corelib and stdlib
; are separate modules, but in no python mode there is no Python stdlib
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Even at the very beginning of the script `(get-atoms &self)`
; returns two atoms. One is from the imported stdlib, and the other
; is corelib, which was a dependency of stdlib that has been promoted
; These atoms are both wrapped spaces, as is `&self`
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
!(assertEqual
((let $x (get-atoms &self) (get-type $x)))
(superpose (((get-type &self)) ((get-type &self)))))
; stdlib is already loaded
!(assertEqual
(if (> 1 2) 1 2)
2)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Importing the module into new space
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
!(import! &m f1_moduleA)
; Check whether passed expression contains atom for which condition is True
(: contains (-> Expression (-> Atom Bool) Bool))
(= (contains $list $condition)
(if (== $list ()) False
(let $head (car-atom $list)
(if ($condition $head) True
(let $tail (cdr-atom $list) (contains $tail $condition)) ))))
; Check whether atom is space comparing its type with type of the &self atom
(: is-space (-> Atom Bool))
(= (is-space $atom)
(let* (($type (get-type $atom)) ($space (get-type &self))) (== $type $space)))
; It's first atom is a space
!(assertEqual
(let $x (collapse (get-atoms &m)) (contains $x is-space))
True)
; FIXME: It is the `stdlib` atom but equality check doesn't work
;!(import! &stdlib top:stdlib)
;!(assertEqual
;(let $x (collapse (get-atoms &m)) (car-atom $x))
;&stdlib)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Without additional means like `(&m.f 2)` notation or `(interpret &m (f 2))`,
; we cannot execute functions from the separate space - we can only use `match`.
; Although `&m` imports another space with definition of `g`, it is not reduced
; because it is not defined in the context of `&self`. This is the expected
; behavior, but it shows that this way of importing spaces is not too useful
; for importing modules with functions.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
!(assertEqual
(match &m (= (f 2) $x) $x)
(g 3))
; Importing the same space into `&self` should break nothing
; TODO? If stdlib space would be in `&m`, which should check that it is not
; there anymore since in should be removed after importing it to `&self`
!(import! &self f1_moduleA)
; Now indirectly imported `g` works and `f` fully works
!(assertEqual (g 2) 102)
!(assertEqual (f 2) 103)
; `&self` contains 4 grounded sub-spaces now:
; - stdlib
; - corelib
; - moduleA itself, which is the same as &m
; - moduleC imported by moduleA and removed from A after its import to &self
; Check whether atom is &m
(: is-m (-> Atom Bool))
(= (is-m $atom) (== $atom &m))
; Assert that the &self space contains the same space as &m, which we imported from moduleA
; TODO: Comparing spaces like this doesn't work because the source module is the same, but a specialized
; clone of the dependent space without transitive-dependencies was created during the import process.
; Ideally, we can rework importing so that a special space copy isn't created, and then comparing
; spaces will work again. But, In my opinion comparing spaces is not a good way to check to see if a
; module has been loaded. I believe a better solution is accessor operations for loaded & imported modules
;
;!(assertEqual
; (let $a (collapse (get-atoms &self)) (contains $a is-m))
; True)
; Check that the &self space contains the corelib child space
; Note: corelib doesn't import any modules into itself, so no space copy is needed
!(import! &corelib top:corelib)
(: is-corelib (-> Atom Bool))
(= (is-corelib $atom) (== $atom &corelib))
!(assertEqual
(let $a (collapse (get-atoms &self)) (contains $a is-corelib))
True)
; Let's check that `if` from stdlib is not duplicated and gives only one result
!(assertEqual
(if (> 1 2) 1 2)
2)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Let's import one more module into `&self` with a diamond dependence
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
!(import! &self f1_moduleB)
; `g` from moduleC imported via two paths as well as `f`, which uses `g`,
; are not duplicated and produce deterministic results
!(assertEqual (g 2) 102)
!(assertEqual (f 2) 103)
; Function declared in different imported modules will still produce
; non-deterministic results
!(assertEqualToResult
(dup 2)
(12 102))
; Let's import f1_moduleB once more. Such import should be ignored and
; thus f, g and dup should remain unchanged.
!(import! &self f1_moduleB)
!(assertEqual (g 2) 102)
!(assertEqual (f 2) 103)
!(assertEqualToResult
(dup 2)
(12 102))