This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I'm learning sml and trying to make a program that simplifies logic formulas. When I try to run this code, I always get the same error, which I cannot figure out. It's always "Error: syntax error: deleting BAR ID DARROW". I've attached the code below:
- fun Simplify (Or(True, _)) = True
= | Simplify (Or(_, True)) = True
= | Simplify (Or(False, False)) = False
= | Simplify (Or(x, False)) = (Simplify x)
= | Simplify (Or(False, x)) = (Simplify x)
= | Simplify (Or (Var (x), Var (y))) = Or (Var (x), Var (y))
= | Simplify (Or (x, y)) = case Simplify x of
= True => True
= | False => Simplify y
= | x' => case Simplify
= | True => True
GC #0.0.0.0.2.85: (2 ms)
= | False => x'
stdIn:50.6-50.15 Error: syntax error: deleting BAR ID DARROW
- | y' => Or(x', y')
= (*And*)
= | Simplify (And(_, False)) = False
stdIn:2.1-2.8 Error: syntax error: deleting BAR ID DARROW
stdIn:54.1-54.11 Error: syntax error: deleting BAR ID
- | Simplify (And(False, _)) = False
stdIn:1.1-2.6 Error: syntax error: deleting BAR ID
- | Simplify (And(True, True)) = True
= | Simplify (And(True, x)) = (Simplify x)
stdIn:1.1-2.6 Error: syntax error: deleting BAR ID
- | Simplify (And(x, True)) = (Simplify x)
= | Simplify (And(Var (x), Var(y))) = And (Var (x), Var (y))
stdIn:1.1-2.6 Error: syntax error: deleting BAR ID
- | Simplify (And (x, y)) = case Simplify x of
stdIn:1.1-2.6 Error: syntax error: deleting BAR ID
stdIn:53.3-57.4 Error: syntax error: deleting CASE ID
- False => False
= | True => Simplify y
stdIn:2.6-62.6 Error: syntax error: deleting DARROW ID BAR
- | x' => case Simplify y of
= | False => False
stdIn:1.5-2.7 Error: syntax error: deleting BAR ID DARROW
- | True => x'
= | y' => And(x', y')
stdIn:1.5-2.9 Error: syntax error: deleting BAR ID DARROW
- (*Not*)
- | Simplify (Not(Not(x))) = (Simplify x)
= | Simplify (Not(True)) = False
stdIn:68.1-68.11 Error: syntax error: deleting BAR ID
- | Simplify (Not(False)) = True
= | Simplify (Not(Var (x))) = (Not (Var x))
stdIn:1.1-68.3 Error: syntax error: deleting BAR ID
GC #0.0.0.0.3.201: (1 ms)
- | Simplify (Not x) = case Simplify x of
stdIn:1.1-68.3 Error: syntax error: deleting BAR ID
stdIn:68.14-71.4 Error: syntax error: deleting CASE ID
- True => False
= | False => True
stdIn:68.3-74.6 Error: syntax error: deleting DARROW ID BAR
- | x' => Not x'
= (*general*)
= | Simplify True = True
stdIn:1.5-68.4 Error: syntax error: deleting BAR ID DARROW
- | Simplify False = False
= | Simplify (Var(x)) = Var(x);
I've added the whole code:
datatype formula =
True
| False
| Var of string
| Not of formula
| And of formula * formula
| Or of formula * formula;
fun Simplify (Or(True, _)) = True
| Simplify (Or(_, True)) = True
| Simplify (Or(False, False)) = False
| Simplify (Or(x, False)) = (Simplify x)
| Simplify (Or(False, x)) = (Simplify x)
| Simplify (Or (Var (x), Var (y))) = Or (Var (x), Var (y))
| Simplify (Or (x, y)) = case Simplify x of
True => True
| False => Simplify y
| x' => case Simplify y of
| True => True
| False => x'
| y' => Or(x', y')
(*And*)
| Simplify (And(_, False)) = False
| Simplify (And(False, _)) = False
| Simplify (And(True, True)) = True
| Simplify (And(True, x)) = (Simplify x)
| Simplify (And(x, True)) = (Simplify x)
| Simplify (And(Var (x), Var(y))) = And (Var (x), Var (y))
| Simplify (And (x, y)) = case Simplify x of
False => False
| True => Simplify y
| x' => case Simplify y of
| False => False
| True => x'
| y' => And(x', y')
(*Not*)
| Simplify (Not(Not(x))) = (Simplify x)
| Simplify (Not(True)) = False
| Simplify (Not(False)) = True
| Simplify (Not(Var (x))) = (Not (Var x))
| Simplify (Not x) = case Simplify x of
True => False
| False => True
| x' => Not x'
(*general*)
| Simplify True = True
| Simplify False = False
| Simplify (Var(x)) = Var(x);
You need to have parenthesis around nested case statements, also when using them and having multiple function clauses, as it is not possible to differentiate the pipe (|) from belonging to the fun clauses or the case clauses.
Also you are missing the "y" argument to simplify in the second case of Simplify (Or (x, y)), and some of your nested case expressions have a starting pipe, where it shouldn't:
fun Simplify (Or (True, _)) = True
| Simplify (Or (_, True)) = True
| Simplify (Or (False, False)) = False
| Simplify (Or (x, False)) = Simplify x
| Simplify (Or (False, x)) = Simplify x
| Simplify (Or (Var x, Var y)) = Or (Var x, Var y)
| Simplify (Or (x, y)) = (case Simplify x of
True => True
| False => Simplify y
| x' => (case Simplify y of
True => True
| False => x'
| y' => Or(x', y')))
(*And*)
| Simplify (And (_, False)) = False
| Simplify (And (False, _)) = False
| Simplify (And (True, True)) = True
| Simplify (And (True, x)) = (Simplify x)
| Simplify (And (x, True)) = (Simplify x)
| Simplify (And (Var x, Var y)) = And (Var x, Var y)
| Simplify (And (x, y)) = (case Simplify x of
False => False
| True => Simplify y
| x' => (case Simplify y of
False => False
| True => x'
| y' => And(x', y')))
(*Not*)
| Simplify (Not (Not x)) = (Simplify x)
| Simplify (Not True) = False
| Simplify (Not False) = True
| Simplify (Not (Var x)) = Not (Var x)
| Simplify (Not x) = (case Simplify x of
True => False
| False => True
| x' => Not x')
(*general*)
| Simplify True = True
| Simplify False = False
| Simplify (Var x) = Var x
Atleast this compiles with this rather wrongish datatype:
datatype Expr = Or of Expr * Expr
| And of Expr * Expr
| Not of Expr
| Var of Expr
| True
| False
Related
So I am new to Haskell and below I have attempted to program a function that takes a given value of e and a given list and determines whether that given value appears in the list given outputting True if the value given does appear and False if not.
inListm e [] = False
inListm e (x:xs)
| e == x = True || inListm e xs
| otherwise = False || inListm e xs
If
inListm 2 [0, 2, 1, 2]
is given, the output would be
True
However, I would like the final output to be in a list like this
[True]
I have attempted to do this by
inListd e [] = False : []
inListd e (x:xs)
| e == x = True : [] || inListd e xs
| otherwise = False :[] || inListd e xs
but all that gives me is an error so I would like to know how I could resolve this
Consider reusing your existing function; reuse is a big part of what makes writing big programs possible. Like this:
inListd e xs = inListm e xs : []
-- OR
inListd e xs = [inListm e xs]
You are on the right track. The only thing necessary is to return a list if you have a result, so:
inListd :: Eq a => a -> [a] -> [Bool]
inListd e [] = [False]
inListd e (x:xs)
| e == x = [True]
| otherwise = inListd e xs
That being said, I does not seem to make much sense to wrap the result in a list.
i have datatype expression defined.
datatype 'a expression = Not of 'a expression
| Or of 'a expression list
| And of 'a expression list
| Eq of 'a expression list
| Imp of 'a expression * 'a expression
| Var of 'a
| True | False;
And i need to implement function of this type
getVars (= ''a expression -> ''a list) goal of this function is to return all Var values in list.
Here is an example of function return.
- getVars (Eq [Var "A", Var "B", Imp (Var "D", Not (Var "Q")), Var "D", Var "B"]); val it = ["A","B","D","Q"] : string list
I have no idea how to implement that. Give me some advice plz.
Since you have provided no attempt, here is a template to get you started:
fun getVars expr =
case expr of
Not subExpr => ...
| Or subExprs => ...
| And subExprs => ...
| ...
Try and provide a bigger attempt to get more specific feedback.
Here is my attempt of solution for this case.
fun getVars expr =
case expr of
Var i => i (*Only those i's are in output list*)
| Not j => getVars(j) (*j is expression so i can use recursion*)
| Or k => map (fn x => getVars(x)) k (*there i need to loop over list and do recursion over every element in list, couse elements are expressions*)
| And k => map (fn x => getVars(x)) k (*same*)
| Eq k => map (fn x => getVars(x)) k (*same*)
| Imp k => (*problem for me couse its not list*)
(*And i need to put solution for True and False too...*);
But this code doesn't output list, only elements, becouse i don't know how to add elements to list if there is a case of no elements added it should return [].
getVars True = [];
getVars Eq [Var 1, Var 2] = [1,2];
getVars Or [Var "te", Var "st"] = ["te", "st"];
getVars And [True, False] = [];
getVars And [Var "st", Var "st"] = ["st"]; (*This one is interesting*)
There is more input and output examples.
I am trying to implement a program that takes a string and a list and returns NONE if it doesn't find any match and the list without the element if it does.
fun all_except_option ("string",["he","she","string"]) = SOME["he","she"]
I have managed to make it working, but without the options type and i have no idea how to make it return SOME list instead a normal list.
fun all_except_option(str,lst)=
case lst of
[] => []
| x::lst' => if same_string(x,str) = false
then let fun append (word, list) = word::list
in append(x,[]) :: all_except_option(str,lst')
end
else all_except_option(str,lst')
Thank you. I managed to make it working, but i still don't understand the "else case" and how is my programm handling it. Here is the working code. I would be glad if you can explain me the "else case all_except_option(str,list') of".
fun all_except_option(str,list)=
case list of
[] => NONE
| x::list' => if same_string(x,str) then
SOME( list')
else case all_except_option(str,list') of
NONE=>NONE
| SOME list'=>SOME(x::list')
implement a program that takes a string and a list and returns NONE if it doesn't find any match and the list without the element if it does.
all_except_option ("string",["he","she","string"]) = SOME ["he","she"]
How is SOME [] different from NONE? As in, if this function returned just a list, it would be possible to say that removing occurrences of "string" results in no other strings: Either the list was empty already, or it contained only occurrences of "string". I am not sure why NONE vs. SOME [] is warranted in one case over the other.
So the better function is one that simply returns a plain list:
fun except (x, ys) = List.filter (fn y => x <> y)
When is it useful to return 'a option?
For example when the return type does not have a way to indicate no result already:
fun lookup k1 [] = NONE
| lookup k1 ((k2,v)::pairs) =
if k1 = k2
then SOME v
else lookup k1 pairs
This function returns 0 or 1 thing. But it's also a simple function because it never aggregates results over its recursion. Recursive functions become complicated when they return composite data types like 'a option when it needs to unpack the result of the recursion.
A good example is an eval function that sometimes fails:
datatype expr
= Add of expr * expr
| Sub of expr * expr
| Mul of expr * expr
| Div of expr * expr
| Int of int
fun eval (Int n) = SOME n
| eval (Add (e1, e2)) = evalHelper ( op+ ) (e1, e2)
| eval (Sub (e1, e2)) = evalHelper ( op- ) (e1, e2)
| eval (Mul (e1, e2)) = evalHelper ( op* ) (e1, e2)
| eval (Div (e1, e2)) =
case eval e1 of
NONE => NONE
| SOME x => case eval e2 of
NONE => NONE
| SOME 0 => NONE
| SOME y => SOME (x div y)
and evalHelper binop (e1, e2) =
case eval e1 of
NONE => NONE
| SOME x => case eval e2 of
NONE => NONE
| SOME y => SOME (binop (x, y))
Here the return type is int option, which means that you most often return an int, but if you ever divide by zero, that results in "no value", so rather than raise an exception, we return NONE, which necessitates us to return SOME n when there is a result, so that the type fits in both cases.
A quick demonstration:
- eval (Div (Int 5, Int 2));
> val it = SOME 2 : int option
- eval (Div (Int 5, Int 0));
> val it = NONE : int option
- eval (Div (Int 2, Sub (Int 3, Int 3)));
> val it = NONE : int option
- eval (Div (Int 0, Int 1));
> val it = SOME 0 : int option
Here SOME 0 actually means "the result is 0", which is not the same as "cannot divide by zero."
How can I write a function in Ocaml, that would accept two boolean values (for instance a and b, that would represent logical values 0 and 1) and a character, that would determine the operation between these two logical values? The function would then return true or false, depending on the corresponding logical value input.
There is both a semantic, as well as a syntax error in this code; well, maybe there are more, but the compiler only made a complaint about this one so far:
line 2, characters 27-30:
Error: This expression has type char but an expression was expected of type
bool
This is what the compiler has stated about the code and here's what I've wrote:
let logic (a, b) operation = match operation with
| true -> if (operation == 'A') then match (a,b) with
| (true, true) -> true
| _ -> false
else if (operation == '0') then match (a,b) with
| (false,false) -> false
| _ -> true
else if (operation == 'X') then match (a,b) with
| (true,true) -> false
| (false,false) -> false
| _ -> true
else if (operation == 'I') then match (a,b) with
| (true, false) -> false
| _ -> true
else then match (a,b) with
| _ -> false
| false -> end;;
logic (a,b) 'A';;
--------------------------------------------------------------------------
OK, I've made some progress,at least it compiles now. However I still get an error, when I try to call the "logic" function with this line:
logic (true, false) 'A';;
The error states this:
Error: This expression has type bool
This is not a function; it cannot be applied.
Here's what I wrote now:
let logic (a, b) operation = match operation with
| 'A' -> (match (a,b) with
| (true, true) -> true
| _ -> false
)
| '0' -> (match (a,b) with
| (false,false) -> false
| _ -> true
)
| 'X' -> (match (a,b) with
| (true,true) -> false
| (false,false) -> false
| _ -> true)
| 'I' -> (match (a,b) with
| (true, false) -> false
| _ -> true
)
| _ -> (match (a,b) with
| _ -> false
)
To expand on the comment of #Elan-Hamburger a little bit.
You have this:
match operation with
| true -> ...
But your operation is a character. So this won't work. You can only match operation against specific characters.
It's especially strange since you later compare operator to various characters using ==. But the match will do that for you.
In other words you can have something like this:
match operation with
| 'A' -> ...
| '0' -> ...
| 'X' -> ...
| 'I' -> ...
| _ -> ...
There are many other problems with your code. Here are some comments:
You have nested match statements, which requires parentheses to work out right. If you try to nest without parentheses there's no way to tell when the inner match is over and further alternatives (starting with |) of the outer match are given.
Nested match statements look like this:
match expr with
| X ab ->
(match ab with
| A -> 4
| B -> 2
)
| Y _ -> 0
(You can also use begin/end instead of parentheses if you prefer the way that looks.)
You're using == to compare values. The ordinary equality comparison operator is =. The special operator == should only be used when you have a specific reason for it.
You have code that reads like this:
else then match ...
This can't be syntactically correct. Possibly the then is left over from an edit.
You can simplify this expression
match (a, b) with
| _ -> false
to this simpler expression:
false
Update
I can't reproduce your new reported problem. In fact your new code works OK for me in two quick tests.
. . .
val logic : bool * bool -> char -> bool = <fun>
# logic (true, false) 'A';;
- : bool = false
# logic (true, true) 'A';;
- : bool = true
Possibly there was some extraneous input (or extraneous definitions) in your top-level session. I suggest just trying again with a fresh session.
let minus = function
| Int.min_value, _ | Int.max_value, _ | _, Int.min_value | _, Int.max_value -> 0
| x, y -> x - y
Error: Parse error: [module_longident] expected after "." (in
[module_longident])
I can't see anything wrong.
I did this in utop with Core.Std opened
Int.min_value and Int.max_value are values, not constructors (names of constructors are capitalized, names of values are not).
You can't use values in a pattern matching, you can only use constructors.
The good code is
let minus (x, y) =
if x = Int.min_value
|| x = Int.max_value
|| y = Int.min_value
|| y = Int.max_value
then
0
else
x - y
your wrong code is equivalent to
let min_value = -1000000
let max_value = 1000000
let minus = function
| min_value, _ | max_value, _ | _, min_value | _, max_value -> 0
| x, y -> x - y
which compiles because it uses correct names (not names from a different module) but produces the wrong result (always 0).