Skip to content

Instantly share code, notes, and snippets.

@mwolicki
Created March 24, 2018 10:52
Show Gist options
  • Save mwolicki/3c0d350401269199c2804d362d7f02d9 to your computer and use it in GitHub Desktop.
Save mwolicki/3c0d350401269199c2804d362d7f02d9 to your computer and use it in GitHub Desktop.
type Value =
| VInt of int
| VStr of string
type Id = Id of string
type Filter =
| All of Filter list
| Any of Filter list
| Not of Filter
| Equals of Id * Value
let (.=.) i v = Equals (Id i, VStr v)
let (.==.) i v = Equals (Id i, VInt v)
let (.&&.) a b = All [a; b]
let (.||.) a b = Any [a; b]
module Eval =
[<AutoOpen>]
module TristateLogic =
type TristateLogic =
| True
| False
| Bottom
let and' a b =
match a, b with
| Bottom, _
| _, Bottom -> Bottom
| True, True -> True
| _ -> False
let or' a b =
match a, b with
| Bottom, _
| _, Bottom -> Bottom
| True, _
| _, True -> True
| _ -> False
let not = function
| True -> False
| False -> True
| Bottom -> Bottom
let exists f =
let rec exists state f = function
| [] -> Bottom
| [x] -> or' (f x) state
| x :: xs ->
match f x with
| Bottom -> Bottom
| state -> exists state f xs
exists False f
let rec forall f =
let rec forall state f = function
| [] -> Bottom
| [x] -> and' (f x) state
| x :: xs ->
match f x with
| Bottom -> Bottom
| state -> forall state f xs
forall True f
let rec eval (data:Map<_,_>) = function
| All fx -> forall (eval data) fx
| Any fx -> exists (eval data) fx
| Not f -> not <| eval data f
| Equals (id, value) ->
match Map.tryFind id data with
| Some v when v = value -> True
| Some _ -> False
| None -> Bottom
let filter data p =
match eval data p with
| True -> true
| _ -> false
let p = "x" .=. "abc" .&&. ("y" .=. "abc")
p |> Eval.eval (Map [Id "x", VStr "abc"; Id "z", VStr "z"])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment