From 3b0485e3d7e8646058a06da2561c6392f1dbda3f Mon Sep 17 00:00:00 2001 From: Finn Teegen Date: Tue, 17 Oct 2017 17:36:59 +0200 Subject: [PATCH] Initial version --- .gitignore | 3 ++ LICENSE | 29 +++++++++++++++ README.md | 4 +++ package.json | 22 ++++++++++++ src/PFLP.curry | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 155 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 package.json create mode 100644 src/PFLP.curry diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e786f71 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*~ +.curry +.cpm diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..2554211 --- /dev/null +++ b/LICENSE @@ -0,0 +1,29 @@ +Copyright (c) 2017, Sandra Dylus, Jan Christiansen, Finn Teegen +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. 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. + +3. Neither the names of the copyright holders nor the names of its + 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 +HOLDER 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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..95dd9ba --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +pflp +==== + +This package provides a library for probabilistic function logic programming. diff --git a/package.json b/package.json new file mode 100644 index 0000000..76bc385 --- /dev/null +++ b/package.json @@ -0,0 +1,22 @@ +{ + "name": "pflp", + "version": "1.0.0", + "author": "Sandra Dylus , Jan Christiansen , Finn Teegen ", + "maintainer": "Finn Teegen ", + "synopsis": "Library for Probabilistic Functional Logic Programming", + "category": [ "Programming" ], + "license": "BSD-3-Clause", + "licenseFile": "LICENSE", + "sourceDirs" : [ "src" ], + "exportedModules": [ "PFLP" ], + "dependencies": { + }, + "compilerCompatibility": { + "kics2": "< 2.0.0", + "pakcs": "< 2.0.0" + }, + "source": { + "git": "https://github.com/finnteegen/pflp.git", + "tag": "$version" + } +} diff --git a/src/PFLP.curry b/src/PFLP.curry new file mode 100644 index 0000000..5624cf3 --- /dev/null +++ b/src/PFLP.curry @@ -0,0 +1,97 @@ +--- Library for Probabilistic Functional Logic Programming +--- @author Sandra Dylus, Jan Christiansen, Finn Teegen +--- @version October 2017 + +module PFLP + ( Probability + , Dist + , enum + , uniform + , certainly + , (>>>=) + , joinWith + , (??) + , RT + , pick + , replicateDist + ) where + +import Float (i2f, (+.), (*.), (/.)) +import Findall (allValues) + +infixl 1 >>>= +infixr 1 ?? + +--- Probabilities. +--- Floating point numbers are used to model probabilities. +type Probability = Float + +--- Probability distributions. +--- Distributions are abstract and can only be created using the functions +--- provided by this library, e.g., 'enum' and 'uniform'. Internally, Curry's +--- built-in non-determinism is used to model distributions with more than one +--- event-probability pair. +data Dist a = Dist { event :: a, prob :: Probability } + +member :: [a] -> a +member = foldr (?) failed + +--- Creates a distribution based on a given list of events and another list +--- providing the corresponding probabilities. This function also ensures that +--- the relevant probabilities add up to `1.0` and are strictly positive. +enum :: [a] -> [Probability] -> Dist a +enum xs ps + | foldl (+.) 0.0 ps' == 1.0 && all (> 0.0) ps' + = member (zipWith Dist xs ps') + | otherwise + = error ("PFLP.enum: probabilities do not add up to 1.0 " ++ + "or are not strictly positive") + where ps' = take (length xs) ps + +--- Creates a uniform distribution based on a given list of events. The list +--- of events must be non-empty. +uniform :: [a] -> Dist a +uniform [] = error "PFLP.uniform: list of events must be non-empty" +uniform xs@(_:_) = enum xs (repeat (1.0 /. i2f (length xs))) + +--- Creates a single-event-distribution with probability `1.0`. +certainly :: a -> Dist a +certainly x = Dist x 1.0 + +--- Combines two (dependent) distributions. +(>>>=) :: Dist a -> (a -> Dist b) -> Dist b +d >>>= f = let Dist x p = d + Dist y q = f x + in Dist y (p *. q) + +--- Combines two (independent) distributions with respect to a given function. +joinWith :: (a -> b -> c) -> Dist a -> Dist b -> Dist c +joinWith f d1 d2 = d1 >>>= \ x -> + d2 >>>= \ y -> + certainly (f x y) + +filterDist :: (a -> Bool) -> Dist a -> Dist a +filterDist p d | p (event d) = d + +--- Queries a distribution for the probabilitiy of events that satisfy a given +--- predicate. +(??) :: (a -> Bool) -> Dist a -> Probability +(??) p = foldr (+.) 0.0 . allValues . prob . filterDist p + +--- Run-time choice values. Currently, the only way to construct a run-time +--- choice value is to explicitly use a lambda abstraction. The evaluation of +--- a run-time choice can be triggered by the function 'pick'. +type RT a = () -> a + +--- Triggers the evaluation of a run-time choice value (see type synonym 'RT'). +--- Everytime a run-time choice value is evaluated, a new choice is made. +pick :: RT a -> a +pick rt = rt () + +--- Independently replicates a distribution a given number of times. In order +--- to behave properly, the given distribution is required to be a run-time +--- choice value (see type synonym 'RT'). +replicateDist :: Int -> RT (Dist a) -> Dist [a] +replicateDist n rt + | n == 0 = certainly [] + | otherwise = joinWith (:) (pick rt) (replicateDist (n - 1) rt)