{"id":18464765,"url":"https://github.com/norfairking/easyspec","last_synced_at":"2025-11-10T00:03:11.751Z","repository":{"id":67627843,"uuid":"83240694","full_name":"NorfairKing/easyspec","owner":"NorfairKing","description":"Signature inference for Functional Property Discovery in Haskell","archived":false,"fork":false,"pushed_at":"2017-09-17T10:58:32.000Z","size":1233,"stargazers_count":38,"open_issues_count":1,"forks_count":2,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-03-23T09:22:07.794Z","etag":null,"topics":["haskell","property-testing","quickcheck","quickspec"],"latest_commit_sha":null,"homepage":"","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/NorfairKing.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-02-26T21:06:20.000Z","updated_at":"2025-01-13T09:09:14.000Z","dependencies_parsed_at":"2023-05-09T14:17:12.632Z","dependency_job_id":null,"html_url":"https://github.com/NorfairKing/easyspec","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NorfairKing%2Feasyspec","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NorfairKing%2Feasyspec/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NorfairKing%2Feasyspec/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NorfairKing%2Feasyspec/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NorfairKing","download_url":"https://codeload.github.com/NorfairKing/easyspec/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247804428,"owners_count":20998977,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["haskell","property-testing","quickcheck","quickspec"],"created_at":"2024-11-06T09:10:59.856Z","updated_at":"2025-11-10T00:03:11.685Z","avatar_url":"https://github.com/NorfairKing.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"Easyspec: Automatic Functional Property Discovery using Signature Inference in Haskell\n======================================================================================\n\n\n# Disclaimer\n\nThis is a proof-of-concept of the automation and the signature inference strategies described in [the master thesis 'Signature inference for functional property discovery and test generation'](https://github.com/NorfairKing/thesis).\nBecause this software was built within the constraints of a master thesis, corners were cut to ensure that the research could be done.\nThis is by no means production-ready.\nThere are a lot of wrinkles to be ironed out before this can be used in practice, but you can already start to play with it.\nThere is more research to be done on this subject, but more importantly more real software engineering.\nPlease [contact the author](https://cs-syd.eu/contact) if you would like to get involved.\n\n# Installing `easyspec` from source\n\nFirst, get the source:\n\n``` shell\ngit clone https://github.com/NorfairKing/easyspec\n```\n\nThen, use [`stack`](https://haskellstack.org/) to install `easyspec`:\n\n``` shell\ncd easyspec\nstack install\n```\n\n# Usage\n\nRunning `easyspec` without arguments or `easyspec --help` will show you the usage of `easyspec`.\n\n# Dependencies\n\nTo discover properties, the internals of the ghc API that `easyspec` uses must have access to `QuickSpec`.\nYou can either install `quickspec` globally with `cabal install quickspec`, or you can have `stack` arrange everything for you by using `stack exec` to run the commands described below.\nFor example, instead of running `easyspec discover MyFile.hs`, you would have to run `stack exec easyspec -- discover MyFile.hs`.\n\n# Discovering properties\n\nTo discover the properties of a functlon `func` in a file `File.hs` in the directory 'example-dir', you can run `easyspec discover File.hs File.func --base-dir example-dir`.\nEasyspec will find all the functions that are in scope at the top-level of a module (including all the imported functions).\nThen it performs its magic and uses `quickspec` to discover the properties of the chosen function with respect to all the other functions in scope.\n\n## Example\n\nThere are plenty of examples in the `examples` directory, but here is a worked example:\n\nSuppose you have the file `MySort.hs` in your working directory with the following contents:\n\n``` Haskell\n{-# LANGUAGE NoImplicitPrelude #-}\n\nmodule MySort where\n\nimport Prelude (Bool(True), otherwise, (\u0026\u0026), Ord((\u003c=)))\n\nmySort :: Ord a =\u003e [a] -\u003e [a]\nmySort [] = []\nmySort (x:xs) = insert (mySort xs)\n  where\n    insert [] = [x]\n    insert (y:ys)\n        | x \u003c= y = x : y : ys\n        | otherwise = y : insert ys\n\nmyIsSorted :: Ord a =\u003e [a] -\u003e Bool\nmyIsSorted [] = True\nmyIsSorted [_] = True\nmyIsSorted (x:y:ls) = x \u003c= y \u0026\u0026 myIsSorted (y : ls)\n```\n\n... and suppose you are interested in the properties of the `mySort` function in this file.\nThis function `mySort` is called the 'focus function'.\nNow you can run `stack exec easyspec -- discover MySort.hs mySort` to discover the properties of `mySort` with respect to the functions that are in scope.\nThe output should look something like the following:\n\n```\n$ ls MySort.hs \nMySort.hs\n$ stack exec easyspec -- discover MySort.hs MySort.mySort\nmyIsSorted (mySort xs) = True\nmySort (mySort xs) = mySort xs\nxs \u003c= mySort xs = myIsSorted xs\nmySort xs \u003c= xs = True\n```\n\nIf you don't specify a focus function, and use the `full-background` strategy, `easyspec` will find the properties of _all_ the functions in scope.\nTake care, this may take a lot longer.\nThe output should look something like the following:\n\n```\n$ stack exec easyspec -- discover MySort.hs MySort.mySort --strategy=full-background\notherwise = True\nx \u0026\u0026 x = x\nx \u0026\u0026 True = x\nTrue \u0026\u0026 x = x\ny \u0026\u0026 x = x \u0026\u0026 y\ny \u003c= y = True\ny \u003c= True = True\nTrue \u003c= x = x\nx \u0026\u0026 (x \u0026\u0026 y) = x \u0026\u0026 y\n(x \u0026\u0026 y) \u0026\u0026 z = x \u0026\u0026 (y \u0026\u0026 z)\nmyIsSorted (mySort xs) = True\nmySort (mySort xs) = mySort xs\n(y \u0026\u0026 y) \u003c= z = y \u003c= (y \u0026\u0026 z)\nxs \u003c= mySort xs = myIsSorted xs\nmySort xs \u003c= xs = True\n```\n\nAs part of the research, multiple signature inference strategies were developed.\nYou can try them out as well using the `--strategy` flag.\n\n# Evaluating strategies and experimenting with strategies using `easyspec-evaluate`\n\n`easyspec-evaluate` is a tool that is used to evaluate the different signature inference strategies, generate plots, and eventually hopefully draw helpful conclusions.\n\nThe main component is a build system that knows how to make, evaluate and plot data.\nYou can use it with `stack exec easyspec-evaluate -- build myTarget`.\nTo build all plots, and transitive dependencies of those plots, use `stack exec easyspec-evaluate -- build analyse`.\n\n\n# Contributions\n\nContributions are welcome in many forms (vaguely in the order of time investment):\n\n- An issue suggesting an improvement\n- An issue that brings a bug to the attention\n- A PR with a file in `examples` that shows functionality that is not shown by other examples.\n- A PR with a file in `examples-wishlist` that shows me that certain functionality is missing.\n- A PR with a failing test case\n- A PR with a bugfix\n- A PR with a new signature inference strategy evaluator\n- A PR with a new signature inference strategy\n- Any work that gets this project closer to being used in production.\n\nMake sure to [install the `zift.hs` script](https://github.com/NorfairKing/zifter) and that any PR passes the continuous integration.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnorfairking%2Feasyspec","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnorfairking%2Feasyspec","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnorfairking%2Feasyspec/lists"}