From: Julien Moutinho Date: Wed, 25 Sep 2024 22:25:24 +0000 (+0200) Subject: init X-Git-Url: https://git.sourcephile.fr/literate-phylomemy-example1.git/commitdiff_plain?ds=sidebyside init --- 4906aa01c6ecb9f5d37f3a3802e325415ab40174 diff --git a/.reuse/dep5 b/.reuse/dep5 new file mode 100644 index 0000000..7afb923 --- /dev/null +++ b/.reuse/dep5 @@ -0,0 +1,8 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: script +Upstream-Contact: Jane Doe +Source: https://example.com/script + +Files: *.lock *.dot .envrc .gitattributes .gitignore .gitmodules +Copyright: Jane Doe +License: CC0-1.0 diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..57e9c93 --- /dev/null +++ b/flake.lock @@ -0,0 +1,318 @@ +{ + "nodes": { + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_2": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems_2" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "git-hooks": { + "inputs": { + "flake-compat": "flake-compat", + "flake-utils": "flake-utils", + "gitignore": "gitignore", + "nixpkgs": [ + "literate-phylomemy", + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable" + }, + "locked": { + "lastModified": 1715609711, + "narHash": "sha256-/5u29K0c+4jyQ8x7dUIEUWlz2BoTSZWUP2quPwFCE7M=", + "owner": "cachix", + "repo": "git-hooks.nix", + "rev": "c182c876690380f8d3b9557c4609472ebfa1b141", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "git-hooks.nix", + "type": "github" + } + }, + "git-hooks_2": { + "inputs": { + "flake-compat": "flake-compat_2", + "flake-utils": "flake-utils_2", + "gitignore": "gitignore_2", + "nixpkgs": [ + "literate-phylomemy", + "logic", + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable_2" + }, + "locked": { + "lastModified": 1715609711, + "narHash": "sha256-/5u29K0c+4jyQ8x7dUIEUWlz2BoTSZWUP2quPwFCE7M=", + "owner": "cachix", + "repo": "git-hooks.nix", + "rev": "c182c876690380f8d3b9557c4609472ebfa1b141", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "git-hooks.nix", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "literate-phylomemy", + "git-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "gitignore_2": { + "inputs": { + "nixpkgs": [ + "literate-phylomemy", + "logic", + "git-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "literate-phylomemy": { + "inputs": { + "git-hooks": "git-hooks", + "logic": "logic", + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "dirtyRev": "058c31897064e6c0ef8cb91618f2633ff3e1b213-dirty", + "dirtyShortRev": "058c318-dirty", + "lastModified": 1727316326, + "narHash": "sha256-WdjF30XcAFyRWTdKKVer1roBEgVyVD1jfPzWJtYbUp4=", + "type": "git", + "url": "file:///home/julm/work/sourcephile/haskell/literate-phylomemy" + }, + "original": { + "type": "git", + "url": "https://seed.radicle.garden/z2364hmzZUAGy1nKdSFa1gLSoUE2M.git" + } + }, + "logic": { + "inputs": { + "git-hooks": "git-hooks_2", + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1726102818, + "narHash": "sha256-SyO5Vw5rzS8vqBYt2EUtk7SDyumUUs8M+HSAyWlIqsw=", + "ref": "refs/heads/main", + "rev": "d22c2c21a71b557bb6cf5cfec2792709a0183af3", + "revCount": 1, + "type": "git", + "url": "file:///home/julm/work/sourcephile/haskell/logic" + }, + "original": { + "type": "git", + "url": "https://radicle-mermet.sourcephile.fr/z3795BqJN8hSMGkyAUr8hHviEEi2H.git" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1716793392, + "narHash": "sha256-ex3nO87EEQhshXd19QSVW5UIXL0pbPuew4q8TdEJQBY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "67a8b308bae9c26be660ccceff3e53a65e01afe1", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1710695816, + "narHash": "sha256-3Eh7fhEID17pv9ZxrPwCLfqXnYP006RKzSs0JptsN84=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "614b4613980a522ba49f0d194531beddbb7220d3", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-stable_2": { + "locked": { + "lastModified": 1710695816, + "narHash": "sha256-3Eh7fhEID17pv9ZxrPwCLfqXnYP006RKzSs0JptsN84=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "614b4613980a522ba49f0d194531beddbb7220d3", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1723556749, + "narHash": "sha256-+CHVZnTnIYRLYsARInHYoWkujzcRkLY/gXm3s5bE52o=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "4a92571f9207810b559c9eac203d1f4d79830073", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1723556749, + "narHash": "sha256-+CHVZnTnIYRLYsARInHYoWkujzcRkLY/gXm3s5bE52o=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "4a92571f9207810b559c9eac203d1f4d79830073", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "root": { + "inputs": { + "literate-phylomemy": "literate-phylomemy", + "nixpkgs": "nixpkgs_3" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..a87037a --- /dev/null +++ b/flake.nix @@ -0,0 +1,79 @@ +# SPDX-FileCopyrightText: 2024 Jane Doe +# SPDX-License-Identifier: CC0-1.0 +{ + description = "A phylomemy script example"; + inputs = { + # Update with: + # nix flake lock --override-input nixpkgs github:NixOS/nixpkgs + nixpkgs.url = "flake:nixpkgs"; + literate-phylomemy.url = "git+https://seed.radicle.garden/z2364hmzZUAGy1nKdSFa1gLSoUE2M.git"; + }; + outputs = + inputs: + let + lib = inputs.nixpkgs.lib; + # Helper to build for each system in `lib.systems.flakeExposed`. + perSystem = + f: + lib.genAttrs lib.systems.flakeExposed ( + system: + f rec { + inherit system; + pkgs = import inputs.nixpkgs { inherit system; }; + haskellPackages = pkgs.haskellPackages; + } + ); + in + { + # `nix -L build` + packages = perSystem ( + { pkgs, system, haskellPackages, ... }: + { + # The Glasgow Haskell Compiler (GHC) + # Here made available as `.#ghc` for script.hs's shebang + ghc = haskellPackages.ghcWithPackages ( + haskellPackages: [ + # Extra Haskell packages available + inputs.literate-phylomemy.packages.${system}.default + haskellPackages.bytestring + haskellPackages.turtle + haskellPackages.pretty-show + ] + ); + ghcid = pkgs.ghcid; + xdot = pkgs.xdot; + # A compiled version of `script.hs` + # (instead of an interpreted one when run as `./script.hs`) + # To avoid writing a `.cabal` file, `ghc --make` is called directly here, + # but should the script become a full fledge executable, + # a `.cabal` file should be written instead. + default = pkgs.stdenv.mkDerivation { + name = "script"; + src = ./.; + buildInputs = [ + inputs.self.packages.${system}.ghc + ]; + buildPhase = '' + mkdir -p $out/bin + ghc -o "$out/bin/script" -O2 --make ./script.hs + ''; + }; + } + ); + # `nix develop` or `direnv allow` + devShells = perSystem ( + { pkgs, system, ... }: + { + default = pkgs.mkShell { + nativeBuildInputs = [ + inputs.self.packages.${system}.ghc + pkgs.haskellPackages.haskell-language-server + pkgs.haskellPackages.hlint + pkgs.reuse + pkgs.xdot + ]; + }; + } + ); + }; +} diff --git a/script.hs b/script.hs new file mode 100755 index 0000000..74613a6 --- /dev/null +++ b/script.hs @@ -0,0 +1,75 @@ +#!/usr/bin/env -S nix -L shell .#ghc .#ghcid .#xdot --command ghcid --test :main +-- Alternatively: #!/usr/bin/env -S nix -L shell .#ghc .#xdot --command runghc +-- SPDX-FileCopyrightText: 2024 Jane Doe +-- SPDX-License-Identifier: CC0-1.0 + +{-# LANGUAGE OverloadedLists #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE ParallelListComp #-} + +import Control.Concurrent.Async qualified as Async +import Data.ByteString.Builder qualified as BS +import Data.Either (fromRight) +import Data.Map.Strict qualified as Map +import Data.Sequence qualified as Seq +import Logic +import Logic.Theory.Arithmetic +import Logic.Theory.Ord +import Numeric.Probability +import Phylomemy qualified as Phylo +import System.IO qualified as Sys +import System.Process qualified as Sys +import Text.Pretty.Simple +-- import Turtle +-- import GHC.Conc + +assertStrictlyPositive :: Ord a => Zeroable a => a -> () ::: a / () > Zero +assertStrictlyPositive i = unitName i Logic./ fromRight undefined (prove (unitName i Logic.Theory.Ord.> zero)) + +main = do + let minSupp = 1 + let minSize = 2 + + let clusters = + Logic.letName rangeToDocs0 $ \rangeToDocs -> + Logic.letName ["a", "b", "c", "d", "e", "F", "g"] $ \roots -> + Phylo.clusterize roots (assertStrictlyPositive minSupp) (assertStrictlyPositive minSize) rangeToDocs + + let phy = Phylo.phylomemy Phylo.jaccardSimilarity (unName <$> clusters) + let dot = Phylo.phylomemyDOT phy + let msf :: Map.Map (Pos, Phylo.Cluster) (Phylo.MST Pos) + = Phylo.branchesMSF phy + + pPrint ("msf", Map.size msf) + Sys.withFile "phylomemy.dot" Sys.WriteMode (`BS.hPutBuilder` dot) + Sys.callProcess "xdot" ["phylomemy.dot"] + +phy :: Phylo.PhylomemyDownstream Int +phy = [ + ] + +newtype Pos = Pos Int deriving (Eq, Ord, Show, Num) + +rangeToDocs0 :: Pos Phylo.:-> Seq.Seq (Phylo.Document Pos) +rangeToDocs0 = + Map.fromList + [ ( Pos rangeIndex + , Seq.fromList + [ Phylo.Document + { Phylo.documentPosition = Pos (2 * rangeIndex + 3 * docIndex) + , Phylo.documentRoots = Map.fromList [(r, ()) | r <- roots] + } + | roots <- docs + | docIndex <- [1 ..] + ] + ) + | docs <- + [ [["a", "b", "c"], ["a", "d", "e"], ["e", "f", "g"]] + , [["a", "b"], ["d", "f"]] + , [["f"], ["d", "f"], ["f", "g", "a"]] + , [["b", "c", "e"], ["a", "d", "e"], ["a", "b", "c"]] + , [["d", "f", "g"], ["b", "f"], ["a", "c", "d"], ["a", "f"]] + , [["c", "d", "g"], ["b", "c", "g"], ["a", "b", "c"], ["e", "g"]] + ] + | rangeIndex <- [1 ..] + ]