[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [xsmith-bugs] Formal parameters created by lambdas not used for creating references



On Tue, Feb 09, 2021 at 10:00:07PM -0800, Danila Fedorin wrote:
Hello!

Sorry about my delayed response; things got busy around the time I sent my
original email!

No worries!

I'm attaching my little attempt at defining a fuzzer.

I'm attaching a modified version.  It's a small diff, and it works on
the current release and git master branch.

The big change is that I added a `Program` node that has a list of
definitions.  I'm sure this is different from what you're going for,
but you could eg. change it into a `Let` form or something if your
language has that.  Anyway, starting from this working version will
probably make it easier to play with the `reference-choice-info`
property.  You can make it stop choosing lifts, then remove the
Program node.  But you should use the git master branch when you do
that.

At some point we will make another release that includes all the
improvements currently on the master branch.  Realistically, everyone
who currently uses Xsmith (read: the Xsmith developers) uses the
master branch because we keep improving the library as we improve our
fuzzers.
#lang clotho
(require xsmith
         xsmith/app
         racr
         racket/pretty
         racket/string
         racket/port)

(define-spec-component bloglang)

(define number (base-type 'number))
(define no-child-types (lambda (n t) (hash)))

(add-to-grammar
  bloglang

  [Program #f ([definitions : Definition *] [main : Definition])
           #:prop type-info [(fresh-type-variable)
                             (λ (n t)
                               (hash-set
                                (for/hash ([c (ast-children
                                               (ast-child 'definitions n))])
                                  (values c (fresh-type-variable)))
                                'main (fresh-type-variable)))]]
  [Definition #f ([type] [name = (fresh-var-name "def")] [body : Expr])
    #:prop binder-info ()
    #:prop type-info [(fresh-type-variable) (lambda (n t) (hash 'body t))]]

  [Expr #f () #:prop may-be-generated #f ]
  [Number Expr ([v = (random 1000)])
    #:prop type-info [(fresh-subtype-of number) no-child-types]]
  [Add Expr ([left : Expr]
             [right : Expr])
    #:prop type-info [(fresh-subtype-of number)
                      (lambda (n t) (hash 'left t 'right t))]]
  
  [Param #f ([type] [name = (fresh-var-name "arg")])
    #:prop binder-info (#:binder-style parameter)
    #:prop type-info [(fresh-type-variable) no-child-types]]
  [Lambda Expr ([param : Param] [body : Expr])
    #:prop wont-over-deepen #t
    #:prop fresh
    (let* ([arg-type (fresh-type-variable)]
           [return-type (fresh-type-variable)]
           [f-type (function-type arg-type return-type)]
           [hole-type (att-value 'xsmith_type (current-hole))]
           [unify-return (unify! f-type hole-type)]
           [explore-return (force-type-exploration-for-node! (current-hole))]
           [parameter (make-fresh-node 'Param
                                       (hash 'type arg-type))])
      (hash 'type hole-type 'param parameter))
    #:prop type-info
    [(function-type (fresh-type-variable) (fresh-type-variable))
     (λ (n t)
        (let* ([arg-type (fresh-type-variable)]
               [return-type (fresh-type-variable)]
               [unify-return (unify! t (function-type arg-type return-type))])
          (hash 'param arg-type
                'body return-type)))]]
  [App Expr ([func : Expr] [arg : Expr])
    #:prop type-info
    [(fresh-type-variable)
     (λ (n t)
       (let* ([arg-type (fresh-type-variable)]
              [return-type (fresh-type-variable)])
         (unify! t return-type)
         (hash 'func (function-type arg-type return-type)
               'arg arg-type)))]]
  [Ref Expr ([name])
       #:prop reference-info (read)
       #:prop type-info [number no-child-types]]
  )

(define (render-child s n)
  (att-value 'xsmith_render-node (ast-child s n)))
(define (render-children s n)
  (map (λ (m) (att-value 'xsmith_render-node m)) (ast-children (ast-child s n))))

(add-property
 bloglang
 render-node-info

 [Program (λ (n) `(begin ,@(render-children 'definitions n) ,(render-child 'main n)))]
 [Definition (λ (n) `(define ,(string->symbol (ast-child 'name n)) ,(render-child 'body n)))]
 
 [Number (λ (n) (ast-child 'v n))]
 [Add (λ (n) `(+ ,(render-child 'left n) ,(render-child 'right n)))]

 [Param (λ (n) (string->symbol (ast-child 'name n)))]
 [Lambda (λ (n) `(lambda (,(render-child 'param n)) ,(render-child 'body n)))]
 [App (λ (n) `(,(render-child 'func n) ,(render-child 'arg n)))]
 [Ref (λ (n) (string->symbol (ast-child 'name n)))]
 )

(define-xsmith-interface-functions
  [bloglang]
  #:program-node Program
  #:type-thunks
  (list
    (λ () number)
    (λ () (function-type (fresh-type-variable) (fresh-type-variable)))))

(module+ main (bloglang-command-line))