// Learn more about F# at http://fsharp.net // See the 'F# Tutorial' project for more help. type Cond = char * bool type P = Cond List * double type Variable = | OneD of Cond * Cond * double | TwoD of Cond * Cond * Cond * double | Prior of Cond * double let getProbability(p) = match p with | OneD(_,_,prob) -> prob | TwoD(_,_,_,prob) -> prob | Prior(_,prob) -> prob let filterCondition (c, b) v = match v with | OneD((pc,pb),_,_) when c = pc && b = pb -> true | OneD(_,(pc,pb),_) when c = pc && b = pb -> true | Prior((pc,pb),_) when c = pc && b = pb -> true | TwoD((pc,pb),_,_,_) when c = pc && b = pb -> true | TwoD(_,(pc,pb),_,_) when c = pc && b = pb -> true | TwoD(_,_,(pc,pb),_) when c = pc && b = pb -> true | _ -> false let reciprocal v = match v with | Prior((pc,pb),p) -> Prior((pc,not pb),1.0-p) | OneD((pc,pb),a,p) -> OneD((pc,not pb),a,1.0-p) | TwoD((pc,pb),a,b,p) -> TwoD((pc,not pb),a,b,1.0-p) let matchProb cond variables = cond |> List.fold (fun s c -> List.filter (filterCondition c) s) variables |> List.head |> getProbability let completeReciprocalVariable variable = variable |> List.map reciprocal |> List.append variable //let addNeg ps = ps concat ps //let pa = [Prior(('a', true), 0.01)] // //let pta = [OneD(('t', true), ('a', true), 0.5); // OneD(('t', true), ('a', false), 0.1)] // //let ps = [Prior(('s', true), 0.5)] // //let pls = [OneD(('l', true), ('s', true), 0.1); // OneD(('l', true), ('s', false), 0.01)] // //let pbs = [OneD(('b', true), ('s', true), 0.6); // OneD(('b', true), ('s', false), 0.3)] let pm = [Prior(('m',true), 0.1)] |> completeReciprocalVariable let pbm = [OneD(('b',true), ('m',true), 0.9); OneD(('b',true), ('m',false), 0.05)] |> completeReciprocalVariable let psm = [OneD(('s',true), ('m',true), 0.6); OneD(('s',true), ('m',false), 0.3)] |> completeReciprocalVariable let pbym = (pm |> matchProb [('m', true)]) * (pbm |> matchProb [('b',true);('m',true)]) , (pm |> matchProb [('m', false)]) * (pbm |> matchProb [('b',true);('m',false)]) let pbysym = (pm |> matchProb [('m', true)]) * (pbm |> matchProb [('b',true);('m',true)]) * (psm |> matchProb [('s',true);('m',true)]), (pm |> matchProb [('m', false)]) * (pbm |> matchProb [('b',true);('m',false)]) * (psm |> matchProb [('s',true);('m',false)]) let ps = [Prior(('s',true), 0.3)] |> completeReciprocalVariable let pr = [Prior(('r',true), 0.2)] |> completeReciprocalVariable let pwsr = [TwoD(('w',true), ('s',true), ('r',true), 0.9); TwoD(('w',true), ('s',true), ('r',false), 0.7); TwoD(('w',true), ('s',false), ('r',true), 0.8); TwoD(('w',true), ('s',false), ('r',false), 0.1); ] |> completeReciprocalVariable let pwyr = (pr |> matchProb [('r', true)]) * ((pwsr |> matchProb [('r',true);('w',true);('s',true)]) * (ps |> matchProb [('s',true)]) + (pwsr |> matchProb [('r',true);('w',true);('s',false)]) * (ps |> matchProb [('s',false)])) [] let main argv = printfn "%A" pwyr 0 // return an integer exit code