trueagi-io / hyperon-experimental

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

How to delay reduction until bindings are ready? #659

Open ngeiswei opened 3 months ago

ngeiswei commented 3 months ago

Describe the bug

The backward chainer requires the interpreter to be able to delay reduction under certain conditions, such as the arguments are fully grounded.

To Reproduce

Run the following MeTTa script

;; Define Nat
(: Nat Type)
(: Z Nat)
(: S (-> Nat Nat))

;; Define greater than zero
(: 0< (-> Number Bool))
(= (0< $x) (< 0 $x))

;; Define backward chainer
(: bc (-> $a                            ; Knowledge base space
          $b                            ; Query
          Nat                           ; Maximum depth
          $b))                          ; Result
;; Base cases
(= (bc $kb (: $prf $ccln) $_) ; Kownledge base look-up
   (match $kb (: $prf $ccln) (: $prf $ccln)))
(= (bc $kb (: CPU (0⍃ $x)) $_) ; CPU check
   (if (0< $x) (: CPU (0⍃ $x)) (empty)))
;; Recursive step
(= (bc $kb (: ($prfabs $prfarg) $ccln) (S $k))
   (let* (((: $prfabs (-> (: $prfarg $prms) $ccln)) ; Recurse on proof abstraction
           (bc $kb (: $prfabs (-> (: $prfarg $prms) $ccln)) $k))
          ((: $prfarg $prms) ; Recurse on proof argument
           (bc $kb (: $prfarg $prms) $k)))
     (: ($prfabs $prfarg) $ccln)))

;; Define knowledge base
!(bind! &kb (new-space))
!(add-atom &kb (: 2 Prime)) ; 2 is a prime number
!(add-atom &kb (: Rule (-> (: $_ (0⍃ $x))   ; If $x is greater than 0
                           (-> (: $x Prime) ; and is a prime number, then
                               (0⍃' $x))))) ; $x is a prime number greater than zero

;; Test backward chainer
!(bc &kb (: $prf (0⍃' $x)) (S (S Z)))

I tried to provide the simplest possible knowledge base, thus the moronic theory used here.

Expected behavior

It should output

[(: ((Rule CPU) 2) (0⍃' 2))]

Actual behavior

It outputs instead

[]

Additional context