How to declare a function so Listn : ' ' a list -> ' ' a list -> bool, listn xs and ys return true.
Example: lisen [#"1" #"2"] , [#"1" "#3"] return false and [#"1" , #"2"] [#"2" , #"1"] return true
Try this:
infix member
fun x member [] = false
| x member (y::ys) = x = y orelse x member ys;
fun listn (x::xs) ys = x member ys andalso listn xs ys
| listn [] _ = true;
Related
Write with OCaml Longest Common Sottosequence (Deep Search)
Consider a finite set S of strings and an integer K. Determine, if it exists, a string x of length greater than or equal to K subsequence of each string s∈S. The problem is solved by using an in-depth search.
I tried it with two strings without k, it works!
this bellow is my code:
(*trasfmorm string in list char*)
let explode s =
let rec exp i l =
if i < 0 then l
else exp (i - 1) (s.[i] :: l)
in
exp (String.length s - 1) []
(*print list of strings*)
let rec print_list_strings = function
| [] -> ()
| e::l ->
print_string e;
print_string "\n";
print_list_strings l
(*print list of char*)
let rec print_list_char = function
| [] -> print_string "\n"
| e::l ->
print_char e;
print_string " ";
print_list_char l
(*between the lists tell me which one is longer*)
let longest xs ys =
if List.length xs > List.length ys then xs
else ys
(*lcs deep*)
let rec lcs a b =
match a, b with
| [], _ | _, [] -> []
| x::xs, y::ys ->
if x = y then
x :: lcs xs ys
else
longest (lcs a ys) (lcs xs b)
(*
On input: "ABCBDAB", "ABCBDAB"
The LCS returned is "BDAB"
*)
let a = "ABCBDAB";;
let b = "ABCBDAB";;
let a = explode a;;
let b = explode b;;
print_list_char (lcs a b);;
But when I start to find the solution for s strings it seems impossible.
For the moment i write the code bellow:
(* function return n-elemt of a list *)
exception Nth
let rec nth n lista =
match (n, lista) with
| (_, []) -> raise Nth
| (0, t::_) -> t
| (n, t::c) -> nth (n-1) c;;
(* functione given input list of char output string *)
let rendi_stringa s =
String.of_seq (List.to_seq s)
(* delete first n-element of a string *)
let rec drop n = function
| [] -> []
| x::xs ->
if n <= 0 then x::xs
else drop (n-1) xs ;;
(*string into a char list*)
let explode s =
let rec exp i l =
if i < 0 then l
else exp (i - 1) (s.[i] :: l)
in
exp (String.length s - 1) []
(*read k-elemt and return a list*)
let rec leggi k =
if k=0 then []
else
let x = read_line() in
(x) :: leggi (k-1)
(*print element list*)
let rec print_list = function
| [] -> ()
| e::l ->
print_string e;
print_string "\n";
print_list l
(*funzione lista string esplosa--> lista di lista*)
let rec explode_list n lista =
if n = 0 then []
else
let x = List.hd lista in
[(explode x)] # explode_list (n-1) (List.tl lista)
(*n-esima raw e m-column of matrix*)
let pos tabla n m =
let lista = (List.nth tabla n) in
List.nth lista m;;
let subset tabella n =
let rec aux solution tot = function
| [] ->
if tot > 0 then raise NotFound
else solution
| x::rest ->
print_string x;
print_string "\n";
aux (x::solution) (tot-1) rest
in
aux [] n tabella
let subset tabella n =
let rec aux solution = function
| [] ->
if List.length solution < n then raise NotFound
else solution
| x::rest -> nuova_funzione (explode x) rest n
in
aux [] n tabella
let nuova_funzione lista_char lista_string n = function
| _, [] -> print_string "non posso piu fare niente, stringhe finite\n"
| [], _ -> print_string "ho finito confronto con la lista\n"
| [] , x::lt ->
if (lcs lista_char (explode x)) > n then
else
let longest xs ys =
if List.length xs > List.length ys then xs
else ys
(*lcs profonda*)
let rec lcs a b =
match a, b with
| [], _ | _, [] -> []
| x::xs, y::ys ->
if x = y then
x :: lcs xs ys
else
longest (lcs a ys) (lcs xs b)
(**)
(*let rec lcs stringhe num = function
| []
| List.length stringhe < num -> []
| *)
(*------------------------main--------------*)
print_string "how many strings?\n";;
let m = read_int();;
print_string "please write your strings\n";;
let lista = leggi m;;
print_string "strings wrote\n";;
print_list lista;;
explode (nth 0 c);;
let a = "ABCBDAB";;
let a = explode a;;
let b = "BDCABA";;
let b = explode b;;
let c = "BADACB";;
let c = explode c;;
My idea was to use Backtracking, but i'm stuck with logical idea, I have no idea to implement it even with pseudocode!
Any idea or advise?
I use this function to filter a list of integers. I'm beggining in SML and I don't know where is the error.
fun filter f = fn [] => []
| fn (x::xs) => if f(x)
then x::(filter f xs) else (filter f xs)
fun g(x) = if x>5 then true else false
val listTest = filter g [1, 2, 4, 6, 8, 10]
Thank you!
Definitions with fn look like definitions with fun, but without the name and an arrow instead of =:
fn a0 => e0
| a1 => e1
| ...
This would be correct:
fun filter f = fn [] => []
| (x::xs) => if f(x)
then x::(filter f xs)
else (filter f xs)
but the common form is
fun filter _ [] = []
| filter f (x::xs) = if f x
then x :: filter f xs
else filter f xs
fun g x = x > 5
You second fn is redundant, please remove it:
fun filter f = fn [] => []
| (x::xs) => if f(x)
then x::(filter f xs) else (filter f xs)
Then it can compile happily:
- use "a.sml";
[opening a.sml]
val filter = fn : ('a -> bool) -> 'a list -> 'a list
val g = fn : int -> bool
val listTest = [6,8,10] : int list
val it = () : unit
BTW, fun g(x) = if x>5 then true else false is not good style. fun g x = x > 5 is better
Background
We are implementing this algorithm in F#.
Here is a little bit more information from Topor (1982) about the notation that the algorithm uses:
Formally, a 't list is either null (denoted nil) or has a hd (which is a 't) and a tl (which is a 't list)... If x is a list, we test whether it is null by writing null x... We create a new list, adding the element a at the front of an existing list x, by writing a:x... We denote the unit list containing the element a by list(a)... list(x) = x:nil.
Question
What we're wondering is how in F# to express those nil, null, and list(nil) values. For instance, should we be using the Option type, an empty list, or something else?
What We Have Tried
let rec kpermute k (xs: 't list) =
let rec mapPerm k xs ys =
match ys with
| [] -> []
| head::tail ->
let kpermuteNext = kpermute (k-1) (removeFirst head xs)
let mapPermNext = mapPerm k xs tail
mapcons head kpermuteNext mapPermNext
match k with
| 0 -> [[]]
| _ when xs.Length < k -> []
| _ -> mapPerm k xs xs
When working with lists, for list(nil) we use [[]] and for nil we use []. While that's fine, there might be a more expressive way to do it. There are also times when we use List.empty<'t list> and List.empty<'t> when the type inference needs more information.
The paper gives you all the answers: nil is []; null x is a test for whether x is the empty list; list(nil) is [[]].
The naïve translation of algorithm B to F# is as follows:
let rec minus a = function
| [] -> failwith "empty list"
| xh :: xt -> if xh = a then xt else xh :: minus a xt
let rec permute2 k x =
if k = 0 then [[]]
elif List.length x < k then []
else mapperm k x x
and mapperm k x = function
| [] -> []
| yh :: yt -> mapcons yh (permute2 (minus yh x)) (mapperm x yt)
and mapcons a ps qs =
match ps with
| [] -> qs
| ph :: pt -> a :: ph :: mapcons a pt qs
I am trying to write a program that checks if the first list is a prefix of the second list. for example, [5,6] is prefix of [1,5,6,7]. here is my working code but basically I don't have an idea on how to do it.
prefix [Int] -> [Int] -> Bool
prefix [] [] = []
prefix y (x:xs)
| x == y = prefix y xs
| otherwise = 0
any help please ?
Your code does not make much sense if we look at the types:
prefix [Int] -> [Int] -> Bool
prefix [] [] = []
prefix y (x:xs)
| x == y = prefix y xs
| otherwise = 0
Since the two arguments are lists ([Int]), this thus means that y is an [Int], x is an Int, and xs is an [Int]. But then you compare x == y, you can not compare a list with an element. (==) is defined as (==) :: Eq a => a -> a -> Bool.
There are also other problems here: you return a list in the first clause, but the return type is a Bool, and later you return a 0 (again, it should be a Bool).
In case we define a function, we first need to define a certain model for it. When is a list l1 a prefix of a list l2? In case l1 is an empty list, then l1 is always a prefix, regardless of the value of the second list, so:
prefix [] _ = True
In case l1 is a list (i.e. (x:xs)), then it is not a prefix in two cases: (1) in case l2 is an empty list; and (2) in case the first item of l2 (y in (y:ys)) is not equal to x, so:
prefix _ [] = False
prefix (x:xs) (y:ys) | x /= y = False
| otherwise = ...
Now the question is what to do with prefix (x:xs) (y:ys) in case x == y. In that case we recurse on the two list, so the result of prefix (x:xs) (y:ys) == prefix xs ys (only in case x == y), so:
| otherwise = prefix xs ys
Or now in full:
prefix :: [Int] -> [Int] -> Bool
prefix [] _ = True
prefix _ [] = False
prefix (x:xs) (y:ys) | x /= y = False
| otherwise = prefix xs ys
We can further generalize the expression to Eq a => [a] -> [a] -> Bool such that it works with any type a that is an Eq instance (so there is a (==) instance defined over a):
prefix :: Eq a => [a] -> [a] -> Bool
prefix [] _ = True
prefix _ [] = False
prefix (x:xs) (y:ys) | x /= y = False
| otherwise = prefix xs ys
We can also swap the conditions, since usually positive logic is easier to understand than negative logic:
prefix :: Eq a => [a] -> [a] -> Bool
prefix [] _ = True
prefix _ [] = False
prefix (x:xs) (y:ys) | x == y = prefix xs ys
| otherwise = False
now we can furthermore remove the guards, and use an (&&) :: Bool -> Bool -> Bool instead:
prefix :: Eq a => [a] -> [a] -> Bool
prefix [] _ = True
prefix _ [] = False
prefix (x:xs) (y:ys) = x == y && prefix xs ys
Just leaving my two cents here with a combination of functions from Prelude:
isPrefix :: Eq a => [a] -> [a] -> Bool
isPrefix l1 l2 = take (length l1) l2 == l1
If L1 = [1,2,3,4,5] and L2 [4,5,6,7,8], I want to return [1,2,3,5,7,8] which are the elements occurring in one list only. I already wrote a function returning the list of items occurring in both lists.
fun exists x nil = false | exists x (h::t) = (x = h) orelse (exists x t);
fun listAnd _ [] = []
| listAnd [] _ = []
| listAnd (x::xs) ys = if exists x ys then x::(listAnd xs ys)
else listAnd xs ys
The list I am looking for should be given by L1#L2 - (ListAnd L1 L2). I also found functions that delete an element and remove Duplicates. I made several attempts at changing the remDup function slightly so that it will leave no trace of ANY items that occured more than once. Could not get it working. I am not sure how to use and combine all those functions to make it work.
fun delete A nil = nil
| delete A (B::R) = if (A=B) then (delete A R) else (B::(delete A R));
fun remDups nil = nil
| remDups (A::R) = (A::(remDups (delete A R)));
If there is a diff function where diff xs ys returns all elements in xs but not in ys, you can implement listOr function easily:
fun listOr xs ys = diff (xs#ys) (listAnd xs ys)
The diff function can be written similarly to listAnd:
fun diff xs [] = xs
| diff [] _ = []
| diff (x::xs) ys = if exists x ys
then diff xs ys
else x::(diff xs ys)