## Saturday, February 27, 2010

Here’s a version with simple certainty factors, which are based on categories. It seeks to prove hypotheses until it finds one that is at least “Likely.” I changed some of the names to be more consistent with common usage. I also cleaned up the F# a bit.

Standard disclaimers and caveats apply: a weekend fun project, not thoroughly tested, use at your own risk.

``open System// See previous post for additional comments.// Formatted for blog width.// Certainty factors based on categories.type Certainty =   | Impossible = 0  | Disproven  = 1  | Unlikely   = 2  | Possible   = 3  | Likely     = 4   | Proven     = 5  | Certain    = 6  // Likely and Unlikely define the boundaries for// acceptance and rejection.  let Likely (c) = c>=Certainty.Likelylet Unlikely (c) = c<=Certainty.Unlikely// Custom Min and Max.let Min c0 c1 =   match (c0<c1) with     | true -> c0     | false -> c1          let Max c0 c1 =   match (c0>c1) with     | true -> c0     | false -> c1// I cleaned up the Consider functions quite a bit.          let ConsiderBase s (b:Lazy<Certainty>) =  printfn "Considering <-- %s" s  printfn "Concluding  --> %s is %s" s (b.Value.ToString())    let Consider s (b:Lazy<Certainty>) = lazy (   ConsiderBase s b  b.Value)let ConsiderImmediate s (b:Lazy<Certainty>) =  ConsiderBase s b  b   // Conjunction functions converted to certainty.  let Conjoin a (b:unit->Certainty) =    match Unlikely(a) with     | true -> a    | false -> Min a (b())let rec ConjunctionPossible (l:Lazy<Certainty> list) =  match l with    | [] -> Certainty.Certain    | h::t ->         match h.IsValueCreated with          | false -> ConjunctionPossible(t)          | true ->               Conjoin                 h.Value                 (fun unit -> ConjunctionPossible(t))let rec ConjunctionEval (l:Lazy<Certainty> list) =  match l with    | [] -> Certainty.Certain    | h::t ->         Conjoin           h.Value           (fun unit -> ConjunctionEval(t))let Conjunction (l:Lazy<Certainty> list) = lazy (  let possible = ConjunctionPossible(l)  match Unlikely(possible) with    | true -> possible    | false -> ConjunctionEval(l))   // Disjunction functions converted to certainty.  let Disjoin a (b:unit->Certainty) =   match Likely(a) with     | true -> a    | false -> Max a (b())  let rec DisjunctionPossible (l:Lazy<Certainty> list) =  match l with    | [] -> Certainty.Impossible    | h::t ->         match h.IsValueCreated with          | false -> Certainty.Certain          | true ->               Disjoin                 h.Value                 (fun unit -> DisjunctionPossible(t))let rec DisjunctionEval (l:Lazy<Certainty> list) =  match l with    | [] -> Certainty.Impossible    | h::t ->         Disjoin           (h.Value)           (fun unit -> DisjunctionEval(t))let Disjunction (l:Lazy<Certainty> list) = lazy (  let possible = DisjunctionPossible(l)  match Unlikely(possible) with    | true -> possible    | false -> DisjunctionEval(l))   // This function will evaluate all hypotheses.  let rec Maximum (l:Lazy<Certainty> list) = lazy (  match l with    | [] -> Certainty.Impossible    | h::t -> Max h.Value (Maximum(t)).Value)    // Sample data.let black =   Consider "black" (lazy Certainty.Possible) let blue =   ConsiderImmediate "blue" (lazy Certainty.Likely)let orange =   Consider "orange" (lazy Certainty.Unlikely)let white =    Consider "white" (lazy Certainty.Likely)let blackAndOrange =   Consider     "blackAndOrange"     (Conjunction [       black;       orange ])let blackAndOrangeOrBlue =   Consider     "blackAndOrangeOrBlue"     (Disjunction [       blackAndOrange;       blue ]) let whiteAndBlack =     Consider     "whiteAndBlack"     (Conjunction [       white;       black ]) let color =    ConsiderImmediate     "colorIsKnown"     (Disjunction [       blackAndOrange;       blackAndOrangeOrBlue;       whiteAndBlack ])       Console.ReadLine() |> ignore``