I have an if/else statement that need to be changed to First Order Logic..
To reduce the number of applications that are used during online classes.
The If/else statement is below this:
For any Students,and any Lecturers
If Students_Open_Other_Applications = true OR Students_in_Class_Session = false
OR Lecturers_in_Class_Session = false AND Class_Mode = "F2F" AND Same_Session = true
THEN Notice_Lecturer = true AND Notice_Students = true
I am actually not quite understand and try build the FOL like this (I dont know is it correct or not)..
∀x ,∀y Students(x),Lecturers(y) [([OpenOtherApp(x) ∨ ¬InClass(x) ∨ ¬InClass(y)] ∧ ClassMode("F2F") ∧ SameSession(x,y))
→ Notice(x) ∧ Notice(y)]
Then, I try to separate it from two perspective:
Students :-
For every students, that open other app or not in class and class mode F2F
then lecturer and student in same class will be noticed
∀xStudents(x) [([OpenOtherApp(x)∨¬InClass(x)] ∧ ClassMode("F2F")) → (Notice(x) ∧ Notice(y))]
Lecturers:-
For every lecturer that not in class and class mode F2F
then lecturer and student in same class will be noticed
∀yLecturers(y) [(¬InClass(y) ∧ ClassMode("F2F")) → (Notice(x) ∧ Notice(y))]
I dont know if those three first order logics are true..
I need to combine both statement into one statement..
Can someone guide me through and thorough way?
Related
let say i have the following facts :
book(65).
own(named('Peter'), 65).
now got the query as a list of clauses :
[what(A), own(named('Peter'), A)]
or
[who(X), book(A), own(X, A)] .
how do I make a rule that accept this list and return the result. Keep in mind that the question could be Why,When,Who...
I went the usual way :
query_lst([]).
%% query_lst([what(Q)|T], Q) :- query_lst(T).
query_lst([H|T]) :- write('?- '),writeln(H),
call(H), query_lst(T).
but this does not allow binding of Q in wh(Q) to the answer which could be in any of the facts that are called by call()
Additional complication I did not forsee is that the query :
(what(A), own(named('Peter'), A).
would fail, because there is no what(X), fact in the DB.
I have to just bind somehow the variable A /that is in what()/ to query_lst(Goals,A) and of course remove what(X) from the list /which i can do with select/3 /
any idea how to bind list-Wh-var to query_lst result ?
my current solution (assumes Q is first element):
query_lst([G|Gs],Res) :- G =.. [Q,Res], member(Q,[what,why,who,when]), lst2conj(Gs,Conj), call(Conj).
Simply convert the list of goals into a conjunction and call it:
list_to_conjunction([], true).
list_to_conjunction([Goal| Goals], Conjunction) :-
list_to_conjunction(Goals, Goal, Conjunction).
list_to_conjunction([], Conjunction, Conjunction).
list_to_conjunction([Next| Goals], Goal, (Goal,Conjunction)) :-
list_to_conjunction(Goals, Next, Conjunction).
Then:
query_list(Goals) :-
list_to_conjunction(Goals, Conjunction),
call(Conjunction).
You got an answer, but it was an answer to your question, not to what you really wanted. Also, you edited your question after you accepted that answer, which isn't very helpful. Typically it's better to open a new question when you have... a new question.
Here is an answer to what you seem to want, which is not exactly what you asked. You have lists of the form [WhPart | Rest] where the WhPart is a wh-word with a variable, and the Rest is a list of goals. You want to execute these goals and get the variable in the wh-term bound.
The good news is that, since the variable in the wh-word also occurs in the goals, it will be bound if you execute them. No extra work is needed. Executing the goals is enough. If the wh-part is really at the start of the list, you can do the whole thing like this:
query([_WhPart | Body]) :-
call_body(Body).
call_body([]).
call_body([Goal | Goals]) :-
call(Goal),
call_body(Goals).
For example:
?- query([who(X), book(A), own(X, A)]).
X = named('Peter'),
A = 65.
?- query([what(A), own(named('Peter'), A)]).
A = 65.
As you can see, there is no need to convert the query to a conjunctive goal: Executing the queries in sequence is exactly the same as executing their conjunction.
Also, it doesn't actually matter which wh-word is used; the only thing that really matters is the variable contained within the term. For this reason the above version does no checking at all, and the _WhPart could be anything. If you want to check that it is a valid term, you can do the following:
query([WhPart | Body]) :-
wh(WhPart),
call_body(Body).
wh(who(_X)).
wh(what(_X)).
wh(when(_X)).
This buys you some "type checking":
?- query([foo(A), own(named('Peter'), A)]).
false.
But not a lot, since you don't know if the wh-word actually fits what is being asked:
?- query([when(A), own(named('Peter'), A)]).
A = 65.
I have the following database scheme:
student: sid
course: pid
prerequisite: cid, precid
records: sid, cid
How do I go about creating a query in relational calculus such that i need to find all courses for which all its prerequisites have been taken by every student who has taken the course PSY100? I want to write this with at least one universal quantification ∀.
My idea was to find courses for which, for all courses to return, and for all students in records, there exist a student who took PSY100, that has also taken the prerequisite of that course to return.
so i have it written like this
{x:cid | ∃ c IN course [c(cid) = x(cid) AND
∀ y IN course ∀ r record
( y(cid) = c(cid) AND r(cid) = c(cid)
→ ∃ p IN prerequisite ( r(cid) = PSY100 AND r(cid) = p(pid) )]
I am really confused about this. I am pretty sure this is wrong. any help would be greatly appreciated!
I am new to Pyomo. I want to add an if..then.. type constraint to my linear programming problem. I have an abstract model and this is an example what I'd like to do:
if node j1 is receiving less than half of its water demand, the minimum flow in the link between j2 and j1 must be set to demand value in j1 (A and B are model variables, d is a known parameter).
if A(j1)<0.5 then B(j2,j1)>=d(j1)
I tried the following when I define model constraints. But since the model has not yet created the instance from its data file, it doesn't recognize j1 and j2.
def rule_(model):
term1=floor(model.A[j1]/0.5)
return (term1*model.B[j1,j2]>term1*mdoel.demand[j1])
model.rule=Constraint(rule=rule_)
If I take these lines after instantiating the model using data file, I think the constraint will not be implemented at all.
Can anyone help with this, please? Thanks.
"If/then" expressions and floor() are not linear, so they can't be inserted directly into a linear program. However, you can get the same effect by setting a binary flag and using that to activate and deactivate the constraint. Note that binary variables are also not linear, but they are commonly handled by mixed-integer solvers.
model.flag = Var(within=Binary)
def set_flag_rule(model):
# force the flag to be set if A[j1] < 0.5
return ((1 - model.flag) * 0.5 <= model.A[j1])
model.set_flag = Constraint(rule=set_flag_rule)
def rule(model):
# force B[j1, j2] to meet demand if the flag is set
return (model.B[j1,j2] >= model.flag * model.demand[j1])
model.rule=Constraint(rule=rule)
I'm experimenting with Prolog and tried to make my own "if-then-else" method, so that I don't use the -> ; method, for experimenting's sake.
My goal is to make it so that there can be nested ifs and elses in my code if required.
Thus far I have got this:
ifthenelse(_, G, G):- G. %no matter the condition, the goals are the same
ifthenelse(true,G,_):- G. %if
ifthenelse(false,_,G):- G. %else
I think my way hardly seems correct. How can I make my own ifthenelse/3 properly?
Thank you
Preface: What you have implemented is, in an important way, a lot better than the built-in construct you mentioned. I will discuss this point in more detail below.
Regarding the literal question: I think you are quite close already, since you can already nest this to some extent:
?- ifthenelse(C1, ifthenelse(C2,X=1,X=2), X=3).
C1 = C2, C2 = true,
X = 1 ;
C1 = true,
C2 = false,
X = 2 ;
C1 = false,
X = 3.
What now remains is to make it nestable in the condition. For this, you need a way to reify the outcome of conditions, that is, to turn the truth value into a Prolog term that you can reason about symbolically.
See if_/3 for more information: Indexing dif/2
A key property this construct preserves is called logical-purity. In particular, do not erroneously commit to one branch if both are logically possible!
Note on purity: From a declarative point of view, what you have implemented is very nice and has a clear logical interpretation. Taking for example the last two clauses, we can read ifthenelse(C,G1,G2) as: If C is true, then the predicate holds if G1 holds. If C is false, then it holds if G2 holds. Perfectly fine. A semantic "if...then" is not in any way problematic; in fact, every single Horn clause can be read in this way, as an implication from right to left.
In contrast, the built-in construct you mention lacks such a declarative reading in general. For example:
?- ( ( X = 1 ; X = 2 ) -> true ; true ).
X = 1.
But on the other hand:
?- X = 2, ( ( X = 1 ; X = 2 ) -> true ; true ).
X = 2.
So adding a constraint has led to a new solution. A classical logician's nightmare.
Your construct avoids such problems, because it does not prematurely commit to any particular branch. This yields a much more versatile predicate that can also be used in other directions. For example, see that all possible solutions are correctly generated:
?- ifthenelse(C, true, true).
true ;
C = true ;
C = false.
So, I highly encourage your way of formulating this: As you have made perfectly clear, it's your own 'if-then-else', and you are using only pure monotonic constructs to express it.
On a psychological note, I generally prefer to give more room to pure declarative constructs and I added this section only because the comments expressed genuine interest in these aspects.
It is known that in order to avoid -> and implement it yourself, you need to use cut (!) to simulate same behavior:
if_then_else(P, Q, R) :- P, !, Q.
if_then_else(P, Q, R) :- R.
where P is the condition Q the then part and R the else part.
I am trying to implement all function in Haskell, it works fine but I think my base case is not good , if I set the result of the base case to False it makes more sense, I mean not of the members of an empty list passes the test condition in real word so answer should be false but on the other hand if I define it to false the whole function does not work properly .
all' test [] = True
all' test (x:xs)
| not (test x) = False
| otherwise = all' test xs
Consider this: for an empty list the predicate holds for all elements in the list.
Why? Because there are no elements that violate it.
Therefore the base case of the empty list is True.
all is intended to have the same meaning as the statement in formal logic, ∀xϵL: test(x) where L is the list that is the first argument. If you aren't familiar with formal logic, the important thing to understand is that this statement "returns" true even for an empty list. This is called vacuous truth (see http://en.wikipedia.org/wiki/Vacuously_true if you are curious).
The fact that returning true on an empty list makes all' easier to implement is a good example of why vacuous truth is a good idea, but if you want to implement it to return False for an empty list all you have to do is add one more case.
all' _ [] = False --here I have changed test to _ since we don't care what it is
all' test x:[] = test x --the new case
all' test (x:xs)
| not (test x) = False
| otherwise = all' test xs
You can also implement this using a fold, like so:
all' test = foldr (&&) True . map test
You can basically imagine this as applying "and" (&&) to every pair of booleans, with the first one being True. If the first one was False, all would return False regardless of the input due to the nature of && (anything anded with False is False.)
For more details of how folds work, see Learn You a Haskell and scroll to "Only folds and horses".