packages feed

ast-path (empty) → 0.1.2

raw patch · 7 files changed

+302/−0 lines, 7 filesdep +ast-pathdep +basedep +tastysetup-changed

Dependencies added: ast-path, base, tasty, tasty-hunit

Files

+ ChangeLog.md view
@@ -0,0 +1,3 @@+## 0.1.0++Initial version
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Keito Kajitani (c) 2019++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Keito Kajitani nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,21 @@+# ast-path++AST-path is a representation for predicting program properties.++AST-path is described in the paper "A General Path-Based Representation for Predicting Program Properties" (PLDI'2018) <https://arxiv.org/abs/1803.09544>+and used at <https://code2vec.org/> and at <https://code2seq.org/>.++```+{-# LANGUAGE DeriveGeneric #-}+import Data.ASTPath++data Tree a = Leaf a | Node (Tree a) (Tree a)+  deriving (Eq, Show, Generic)++instance AST a => AST (Tree a)+instance AST Int where+  astPathWithHalf = terminalPath show++>>> astPath $ Node (Leaf 0) (Node (Leaf 1) (Leaf 2))+[("Node",["Leaf","1"],["Leaf","2"]),("Node",["Leaf","0"],["Node","Leaf","1"]),("Node",["Leaf","0"],["Node","Leaf","2"])]+```
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ ast-path.cabal view
@@ -0,0 +1,55 @@+cabal-version: 1.12++-- This file has been generated from package.yaml by hpack version 0.31.1.+--+-- see: https://github.com/sol/hpack+--+-- hash: 7286c954518553459704368e3c5eb84afe6a8f7181d03ce1aba6dda8e981cc73++name:           ast-path+version:        0.1.2+synopsis:       vocabulary representation for predicting program properties++description:    Please see the README on GitHub at <https://github.com/ijaketak/ast-path#readme>+category:       Data, Natural Language Processing+homepage:       https://github.com/ijaketak/ast-path#readme+bug-reports:    https://github.com/ijaketak/ast-path/issues+author:         Keito Kajitani+maintainer:     ijaketak@gmail.com+copyright:      2019 Keito Kajitani+license:        BSD3+license-file:   LICENSE+build-type:     Simple+extra-source-files:+    README.md+    ChangeLog.md++source-repository head+  type: git+  location: https://github.com/ijaketak/ast-path++library+  exposed-modules:+      Data.ASTPath+  other-modules:+      Paths_ast_path+  hs-source-dirs:+      src+  build-depends:+      base >=4.7 && <5+  default-language: Haskell2010++test-suite ast-path-test+  type: exitcode-stdio-1.0+  main-is: Main.hs+  other-modules:+      Paths_ast_path+  hs-source-dirs:+      test+  ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wno-missing-methods+  build-depends:+      ast-path+    , base >=4.7 && <5+    , tasty+    , tasty-hunit+  default-language: Haskell2010
+ src/Data/ASTPath.hs view
@@ -0,0 +1,100 @@+-- | AST-path is a representation for predicting program properties.++{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeSynonymInstances #-}++module Data.ASTPath+  ( type HalfPath+  , type ASTPath+  , astPath+  , AST(..)+  , treePath+  , terminalPath+  , AST'(..)+  ) where++import GHC.Generics++type HalfPath = [String]++-- | (top node, [..., start node], [..., end node])+type ASTPath = (String, HalfPath, HalfPath)++-- | Typeclass for tree or terminal node.+class AST a where+  {-# MINIMAL astPathWithHalf #-}+  -- | Generate paths and half paths for recursion.+  astPathWithHalf+    :: a -- ^ current tree+    -> String -- ^ label of current root node+    -> ([ASTPath], [HalfPath]) -- ^ paths and half paths+  default astPathWithHalf :: (Generic a, AST' (Rep a)) => a -> String -> ([ASTPath], [HalfPath])+  astPathWithHalf = treePath++-- | Default implementation for tree type.+treePath :: forall a. (Generic a, AST' (Rep a)) => a -> String -> ([ASTPath], [HalfPath])+treePath a c = astPathWithHalf' (from a :: Rep a a) c++-- | Typical implementation for terminal node type.+terminalPath :: (a -> String) -> a -> String -> ([ASTPath], [HalfPath])+terminalPath f x _ = ([], [[f x]])++-- | Generate AST-paths from tree.+astPath :: AST a => a -> [ASTPath]+astPath a = fst $ astPathWithHalf a undefined++-- | Class of generic representation types that can be parsed into paths.+class AST' f where+  -- | Default implementation for generic instances of `AST`.+  astPathWithHalf' :: f a -> String -> ([ASTPath], [HalfPath])++instance AST' V1 where+  astPathWithHalf' _ _ = undefined++instance AST' U1 where+  astPathWithHalf' _ _ = ([], [])++instance (AST' f, AST' g) => AST' (f :+: g) where+  astPathWithHalf' (L1 a) = astPathWithHalf' a+  astPathWithHalf' (R1 a) = astPathWithHalf' a++instance (AST' f, AST' g) => AST' (f :*: g) where+  astPathWithHalf' (a :*: b) c = (ps, hs)+   where+    (psa, hsa) = astPathWithHalf' a c+    (psb, hsb) = astPathWithHalf' b c+    ps = psa ++ psb ++ [ (c, p1, p2) | p1 <- hsa, p2 <- hsb ]+    hs = hsa ++ hsb++instance (AST a) => AST' (K1 i a) where+  astPathWithHalf' (K1 a) = astPathWithHalf (a :: a)++instance (AST' f, Datatype d) => AST' (D1 d f) where+  astPathWithHalf' (M1 a) = astPathWithHalf' a++instance (AST' f, Constructor c) => AST' (C1 c f) where+  astPathWithHalf' (M1 a) _ = (ps, map (c:) hs)+   where+    (ps, hs) = astPathWithHalf' a c+    c = conName (undefined :: t c f a)++instance (AST' f, Selector s) => AST' (S1 s f) where+  astPathWithHalf' (M1 a) = astPathWithHalf' a++-- | Constructor of list type is ignored, same as generic product type.+-- Hence list type itself cannot be used with `astPath`.+-- If want to use, supply root node label.+instance AST a => AST [a] where+  astPathWithHalf [] _ = ([], [])+  astPathWithHalf (x:xs) c = (ps, hs)+   where+    (psh, hsh) = astPathWithHalf x c+    (pst, hst) = astPathWithHalf xs c+    ps = psh ++ pst ++ [ (c, p1, p2) | p1 <- hsh, p2 <- hst ]+    hs = hsh ++ hst
+ test/Main.hs view
@@ -0,0 +1,91 @@+{-# LANGUAGE DeriveGeneric #-}++module Main where++import Data.ASTPath+import GHC.Generics+import Test.Tasty+import Test.Tasty.HUnit++data Tree a = Leaf a | Node (Tree a) (Tree a)+  deriving (Eq, Show, Generic)++data Exp2 a+  = Val a+  | Term (Exp1 a)+  | Add [Exp2 a]+  deriving (Eq, Show, Generic)++data Exp1 a+  = Par (Exp2 a)+  | Mul [Exp1 a]+  deriving (Eq, Show, Generic)++instance AST a => AST (Tree a)+instance AST a => AST (Exp1 a)+instance AST a => AST (Exp2 a)++instance AST Int where+  astPathWithHalf = terminalPath show++main :: IO ()+main = do+  defaultMain $ unitTests++unitTests :: TestTree+unitTests = testGroup "unit tests"+  [ testCase "simple tree" $ do+    let tr :: Tree Int+        tr = Node (Leaf 0) (Leaf 1)+        path = astPath tr+        n = "Node"+        l = "Leaf"+    assertBool "single path" $+      (n, [l, "0"], [l, "1"]) `elem` path+  , testCase "complex tree" $ do+    let tr :: Tree Int+        tr = Node (Leaf 0) (Node (Leaf 1) (Node (Leaf 2) (Leaf 3)))+        path = astPath tr+        n = "Node"+        l = "Leaf"+    assertBool "path 1" $+      (n, [l, "2"], [l, "3"]) `elem` path+    assertBool "path 2" $+      (n, [l, "1"], [n, l, "2"]) `elem` path+    assertBool "path 3" $+      (n, [l, "1"], [n, l, "3"]) `elem` path+    assertBool "path 4" $+      (n, [l, "0"], [n, l, "1"]) `elem` path+    assertBool "path 5" $+      (n, [l, "0"], [n, n, l, "2"]) `elem` path+    assertBool "path 6" $+      (n, [l, "0"], [n, n, l, "3"]) `elem` path+  , testCase "arithmetics" $ do+    let ex :: Exp1 Int+        ex = Mul [Par (Add [Val 5,Val 3]), Par (Add [Val 4, Val 2,Val 1])]+        path = astPath ex+        v = "Val"+        p = "Par"+        a = "Add"+        m = "Mul"+    assertBool "path 1" $+      (a, [v, "5"], [v, "3"]) `elem` path+    assertBool "path 2" $+      (a, [v, "2"], [v, "1"]) `elem` path+    assertBool "path 3" $+      (a, [v, "4"], [v, "2"]) `elem` path+    assertBool "path 4" $+      (a, [v, "4"], [v, "1"]) `elem` path+    assertBool "path 5" $+      (m, [p, a, v, "5"], [p, a, v, "4"]) `elem` path+    assertBool "path 6" $+      (m, [p, a, v, "5"], [p, a, v, "2"]) `elem` path+    assertBool "path 7" $+      (m, [p, a, v, "5"], [p, a, v, "1"]) `elem` path+    assertBool "path 8" $+      (m, [p, a, v, "3"], [p, a, v, "4"]) `elem` path+    assertBool "path 9" $+      (m, [p, a, v, "3"], [p, a, v, "2"]) `elem` path+    assertBool "path 10" $+      (m, [p, a, v, "3"], [p, a, v, "1"]) `elem` path+  ]