Infer incomplete rules - business-rules

How can I infer rules with incomplete facts as input?
For example, I only has X eat flies as input:
- {cf(croaks) 1.0}, {cf(eats flies) 1.0}, {cf(a frog) 1.0}
- If X 'croaks' and X 'eats flies' Then X is 'a frog' {cf 1.0}
If X is 'a frog' Then X is 'green' {cf 1.0}
How can I infer X is green with some percentage accuracy?

Related

How to compare sublists in List[List[Double]]

I have a List[List[Double]]
Ignoring the last element of each list with in outer list, I want to compare inner lists i.e. we have a
List(
List(0.1,0.5,0.3,0),
List(2.3,0.1,0.4,1),
List(0.1,0.5,0.3,1)
)
I want distinct list ignoring last element i.e.
List(
List(0.1,0.5,0.3,0),
List(2.3,0.1,0.4,1)
)
Here the 1st and last lists are similar ignoring the last elements.
kindly provide me some clue. As I am very new to scala.
Study the Standard Library. It's amazing the things you can find there.
List(List(0.1,0.5,0.3,0),List(2.3,0.1,0.4,1),List(0.1,0.5,0.3,1)).distinctBy(_.init)
//res0: List[List[Double]] = List(List(0.1, 0.5, 0.3, 0.0), List(2.3, 0.1, 0.4, 1.0))
If you're on Scala 2.13+ please see #jwvh's solution, otherwise ...
You could traverse the list via foldLeft to assemble a new list of inner lists by checking against a Set of lists with distinct init:
val list = List(List(0.1, 0.5, 0.3, 0.0), List(2.3, 0.1, 0.4, 1.0), List(0.1, 0.5, 0.3, 1.0))
list.foldLeft((List[List[Double]](), Set[List[Double]]())){ case ((ls, s), l) =>
val lInit = l.init
if (s.contains(lInit)) (ls, s) else (l :: ls, s + lInit)
}._1.reverse
// res1: List[List[Double]] = List(List(0.1, 0.5, 0.3, 0.0), List(2.3, 0.1, 0.4, 1.0))
In case order of the resulting inner lists is unimportant, an alternative is to group the list by the inner list's init, followed by extracting the first inner list from the grouped Map values:
list.groupBy(_.init).map(_._2.head)
// res2: List[List[Double]] = List(List(2.3, 0.1, 0.4, 1.0), List(0.1, 0.5, 0.3, 0.0))

Converting int to real in SML

Newbie at SML
I have the following code that returns the absolute value of a list. I need it to be of type int list -> real list. Where do I place the statement that converts it to real while constraining this code to a single line?
val myabs = map(fn x => if x >= 0 then x else ~x) [1,~2, 3, ~4];
You convert an int to real using Real.fromInt:
- Real.fromInt 42;
> val it = 42.0 : real
You can convert an int list into a real list by List.map Real.fromInt:
- List.map Real.fromInt [1, 2, 3];
> val it = [1.0, 2.0, 3.0] : real list
You can convert an integer to its absolute using Int.abs:
- Int.abs ~42;
> val it = 42 : int
You can combine those two functions and so both convert an integer to its absolute and convert it to real:
- (Real.fromInt o Int.abs) ~42;
> val it = 42.0 : real
And you can do this for an entire list using List.map (Real.fromInt o Int.abs):
- List.map (Real.fromInt o Int.abs) [~1, ~2, ~3];
> val it = [1.0, 2.0, 3.0] : real list
You can express that as a single function:
fun myabs xs = List.map (fn x => Real.fromInt (Int.abs x)) xs
And you can shorten this function a bit:
val myabs = List.map (fn x => Real.fromInt (Int.abs x))
val myabs = List.map (fn x => (Real.fromInt o Int.abs) x)
val myabs = List.map (Real.fromInt o Int.abs)
So the only missing pieces were:
Instead of if x >= 0 then x else ~x, use Int.abs x.
To convert x to real, use Real.fromInt x.
To apply multiple functions in sequence, f (g x) or (f o g) x, like math.

Addition of tow list with different list lengthes

I am trying to remove the strings from a list and then find the sum of the new list with a list which has smaller length.
I have written a code which does not work at 3-4 places. I have some question,
why does the if statement does not work propely?
How can I write the addition function for this kind of list with differnt lenght?
This is my code:
def remove_text_from_list(the_list):
z = []
for x in the_list:
if isinstance(x, float):
z.append(x)
return z
def add(a,b):
return a+b
x = []
list1=['s', 1.0, 2.0, 'a', 3.0, 4.0,'b', 5.0, 6.0,'c', 7.0, 8.0]
list2=[10.0, 20.0]
newlist=remove_text_from_list(list1)
for i in newlist:
for j in list2:
f = add(i,j)
final_list.append(f)
print(x)
The desired result should be like following:
final_list=[11,22,13,24,15,26,17,28]
Use a generator expression to create a generator that yields floats from list1. Use itertools.cycle to iterate over list2 repeatedly as needed. Use zip to pair the floats from list1 with the cycled items from list2 and add them together in a list comprehension.
>>> from itertools import cycle
>>> just_floats = (i for i in list1 if isinstance(i, float))
>>> [a+b for a, b in zip(just_floats, cycle(list2))]
[11.0, 22.0, 13.0, 24.0, 15.0, 26.0, 17.0, 28.0]
You return the list in the if-statement. If you do it at the end of the for-loop it should work:
def remove_text_from_list(the_list):
z = []
for x in the_list:
if isinstance(x, float):
z.append(x)
return z
But still x will not be your expected final_result but:
x = [11.0, 21.0, 12.0, 22.0, 13.0, 23.0, 14.0, 24.0, 15.0, 25.0, 16.0, 26.0, 17.0, 27.0, 18.0, 28.0]

Haskell split list determined by sum value

Hi all I am just a starter on Haskell. I have this list [1.0, 2.0, 1.5, 1.5, n-1]. How would I split this list to sub-list for example [3.0, 3.0,etc]. That is when added the values of the list, when the sum equals the given number(in this case 3), separates the list. I hope this question makes sense. Could someone point me out if there is a function in Data.List which can do this? or even the filter function. The only thing I have so far is:
import Data.List
import Text.Printf
--separate :: [Double] -> [(Double)]
separate = sum [1.0, 2.0, 0.5, 2.5, 3.0, 1.1, 2.0] -- [(1.0, 2.0),(0.5, 2.5),(3.0),(1.1,2.0)] (desired list)
main = do
putStrLn (printf "list : %s" $ show separate)
More precisely, the requirements are:
separate :: Double -> [Double] -> [[Double]]
where separate t xs = ys implies
concat ys = xs
all (near t . sum) ys, where near t x is a predicate stating that x is "close" to t (semi-formal requirement).
a recursive function can be written as
split :: [Double] -> [[Double]]
split x = go x [] 0
where go [] _ _ = []
go (x:xs) acc s | x+s>=3 = (acc++[x]) : go xs [] 0
| otherwise = go xs (acc++[x]) (s+x)
split [1.0,2.0,0.5,2.5,3.0,1.1,2.0]
[[1.0,2.0],[0.5,2.5],[3.0],[1.1,2.0]]
carry an accumulator and sum so far, decide to carry forward or split based on the sum.
Note that, this is constructing "at least", not "near". So all sublists will be greater or equal to 3.0.

Type declaration in tuple unpacking

Given a type:
type coords = int * int
The following works:
# let c : coords = 3, 4;;
val c : coords = (3, 4)
I would also like to be able to do:
# let (x, y) : coords = 3, 4;;
let (x, y) : coords = 3, 4;;
Error: Syntax error
But it complains about a syntax error on :. Is this syntactically possible?
The syntax let x : t = … is the no-argument case of the more general syntax
let f a1 … an : t = …
where t is the return type of the function f. The identifier f has to be just an identifier, you can't have a pattern there. You can also write something like
let (x, y) = …
Here (x, y) is a pattern. Type annotations can appear in patterns, but they must be surrounded by parentheses (like in expressions), so you need to write
let ((x, y) : coords) = …
Note that this annotation is useless except for some cosmetic report messages; x and y still have the type int, and (x, y) has the type int * int anyway. If you don't want coordinates to be the same type as integers, you need to introduce a constructor:
type coords = Coords of int * int
let xy = Coords (3, 4)
If you do that, an individual coordinate is still an integer, but a pair of coordinates is a constructed object that has its own type. To get at the value of one coordinate, the constructor must be included in the pattern matching:
let longitude (c : coords) = match c with Coords (x, y) -> x
The syntax
let x : t = ...
means that you are, in most cases needlessly, telling the compiler that the type of the name x is t (or maybe you just want to add this type information for readability purposes). In your example:
let (x,y) : coords =
you have to ask yourself: what is the name whose type is coords? Clearly you define no such name, the type of x is int and so is the type of y. There's no name with type coords on the left side. If you already have a coords value, you can split it up as below:
# type coords = int*int ;;
type coords = int * int
# let c:coords = 3,4 ;;
val c : coords = (3, 4)
# let x,y = c;;
val x : int = 3
val y : int = 4
In the above example on the line
let c: coords = 3,4 ;;
you are actually letting the compiler that the name c should be assigned a coords type (otherwise int*int will be used as the type).