-1

I'm trying to re-write / translate logic statements written arithmetically, into strings of min/max functions, some of them fairly complicated. Preferably using things like sed, awk, perl, python, etc. I'm working with a program in which, for my purposes, AND=MIN and OR=MAX. I'm able to convert/rewrite XOR, IMPL, etc. so that it understands accordingly without issue - what I'm struggling with (and looking to automate) is the rearranging of the syntax.

A complex example (partially based on a constructive dilemma):

((p implies q) and (r implies s)) and (p or r)

Would be:

min(min(max(~p,q),max(~r,s)),max(p,r))

I just need to convert from the first format to the second (doesn't need to work in reverse). I can convert individual elements (like a single "(p or r)" to "max(p,r)", in isolation) but once it comes time to re-arrange and nest them relative to eachother I'm pretty lost.

4
  • Why is this tagged bash and python? What exactly falls under etc, when you talk about using things like ....? Commented Jan 22, 2024 at 13:23
  • idownvotedbecau.se/noattempt Commented Jan 22, 2024 at 13:24
  • You don't convert directly from the first to the last. You parse the first into an tree, perhaps represented as a nested tuple like ("and", ("and", ("implies", p, q), ("implies", r, s)), ("or", p, r)). Then you recursively "evaluate" the tree using simple rules like eval x = x, eval ("and", p, q) = ("max", eval(p), eval(q)), eval ("implies", p, q) = eval ("or", eval(("not", p)), eval("q")), etc. Commented Jan 23, 2024 at 14:58
  • Forget about using bash for this; it simply does not have the data-structure support needed to write this kind of code easily. Commented Jan 23, 2024 at 14:59

1 Answer 1

1

Using TXR Lisp:

$ txr -i minmax.tl
TXR's suggested retail price is $0. (More in Canada.)
1> (mmax '(((p implies q) and (r implies s)) and (p or r)))
"min(min(max(~p,q),max(~r,s)),max(p,r))"

Code in minmax.tl:

(defun mmax (expr)
  (match-case expr
    ((@left and @right) `min(@(mmax left),@(mmax right))`)
    ((@left or @right) `max(@(mmax left),@(mmax right))`)
    ((not @term) `~@(mmax term)`)
    ((@left implies @right) `max(~@(mmax left),@(mmax right))`)
    (@else `@else`)))

From the system command line:

$ txr -e '(load "minmax")' -P "(mmax '(a and b))"
min(a,b)

From standard input:

$ echo '(a and b)' | txr -e '(load "minmax")' -P "(mmax (read))"
min(a,b)

We can make a little filtering program like this, and give it execute permissions:

$ echo '(a and b)' | ./mmax.tl
min(a,b)

where mmax.tl has execute permissions (chmod +x mmax.tl) and contains:

#!/usr/bin/env txr

(defun mmax (expr)
  (match-case expr
    ((@left and @right) `min(@(mmax left),@(mmax right))`)
    ((@left or @right) `max(@(mmax left),@(mmax right))`)
    ((not @term) `~@(mmax term)`)
    ((@left implies @right) `max(~@(mmax left),@(mmax right))`)
    (@else `@else`)))

(flow (read)
  mmax
  put-line)

Note: (read) reads an object in TXR Lisp syntax. For the example given, it is compatible: (a and (b or c)) is valid. It might not be true of all examples of that input language, in which case we need custom parsing. YMMV.

Sign up to request clarification or add additional context in comments.

3 Comments

Never heard of this, but it certainly looks useful - i'll do some research on this and give it a shot. Thanks!
Just started messing with it and I'm already learning a lot of useful stuff, so thank you for that. The man file is enormous... off the top of your head would you know the right syntax for doing what you showed earlier on the command line? i've tried running without -i and with -n
poured over the man file and google for a good 2 hours trying to deduce how to replicate what you showed me how to do in interactive mode, on the command line, still no luck. i guess i should've specified interactive mode solutions are good for single/handfuls of conversions but if I want to do, say, hundreds, its not really practical.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.