How to proceed from G3 to G4?
I'm trying to apply candidate elimination for the following table and achieve specific and generic boundaries.
S0 : <0 0 0 0 0 0> G0: <? ? ? ? ? ?>
Negative D1 : <Green Normal Yes String Good Same>
S1 = S0
G1 = <Dry ? ? ? ? ?>
<? Hot ? ? ? ?>
<? ? No ? ? ?>
<? ? ? Normal ? ?>
<? ? ? ? Avg ?>
<? ? ? ? ? Change>
Negative D2 : <Green Normal Yes Strong Avg Same>
S2 = S0
G2 = <Dry ? ? ? ? ?>
<? Hot ? ? ? ?>
<? ? No ? ? ?>
<? ? ? Normal ? ?>
<? ? ? ? ? Change>
Positive D3 : <Dry Normal No Normal Avg Change>
S3 = <Dry Normal No Normal Avg Change>
G3 = <Dry ? ? ? ? ?>
<? ? No ? ? ?>
<? ? ? Normal ? ?>
<? ? ? ? ? Change>
Negative : D4 :<Dry Hot No Normal Good Change>
If I remove dissimilar ones from G, all elements will be removed.
How to proceed from G3 to G4?
Go by the algorithm of Candidate Elimination. According to the algorithm, if negative, first remove inconsistent hypothesis from S.
Therefore, S4 :<D N N ? A ?>
As for G, you have to remove each inconsistent hypothesis, and add the ones that match the algorithm.
As you can see, all the hypothesis in current G3 are inconsistent, therefore we remove each of them.
And then we add all minimal specializations of them (i.e. the combinations of 2 items). The combinations must satisfy S while NOT satisfying D (since D is negative)
That basically means to consider all 2-item combinations in S4, and remove ones that are inconsistent with D4.
Negative : D4 :<Dry Hot No Normal Good Change>
S4 :<D N N ? A ?>
And one combination is <D N ? ? ? ?> and that is consistent with D so we keep it.
Another combination is <D ? N ? ? ?> but it satisfies D (therefore inconsistent because D is negative). So we don't keep it.
Likewise G4 can be calculated as
G4 : { <D N ? ? ? ?> <D ? ? ? A ?>
<? N N ? ? ?> <? N ? N ? ?> <? N ? ? ? C>
<? ? N ? A ?>
<? ? ? N A ?>
<? ? ? ? A C>
}
Related
I'm new to Z3py and I found an exercise where it would ask to check if some verification conditions were true. Up to this moment, the exercises I've done were basically to transform simple propositional formulas into z3py clauses, something like:
Propositional Formula would be:
(n>=4) -> (x = y +2)
Which would become in Z3Py:
n, x, y = Ints('n x y')
s.add(Implies(n>=5, x == y+3))
The conditions I'm presented now, introduce Arrays and Quantifiers and after spending hours trying to figure it out on the documentation around, I'm still not able to get it properly done.
For example, how would I do the same process above but with the following conditions:
n ≥ 1 ∧ i = 1 ∧ m = A[0]
i <= n ∧ ∀j. 0 ≤ j < i → m ≥ A[j]
A little snippet of what I think that is correctly done:
i, n = Ints('i n')
s.add(And(n>=1, i == 1, ???)
s.add(And(i<=n,Implies(???))
How should I replace the ??? so that the conditions would be correctly transformed into Z3Py?
Solution:
- The constraint
n ≥ 1 ∧ i = 1 ∧ m = A[0]
would become in Z3Py:
A = Array('A', IntSort(), IntSort()) //Array declaration
i, n, m, j = Ints('i n m j') //Ints declaration for both constraints
And(n>=1, i==1, m==A[0])
- The constraint
i <= n ∧ ∀j. 0 ≤ j < i → m ≥ A[j]
would become:
And(i<=n,ForAll(j,Implies(And(j>=0,j<i),m>=A[j])))
Your questions is quite ambiguous. Note that you've the constraints:
n ≥ 1 ∧ i = 1
and then
i <= n
but that consequent is already implied by the first, and hence is redundant. Meaning, if you add them both to the solver like you did with your s.add lines, then it won't really mean much of anything at all.
I'm guessing these two lines actually arise in different "subparts" of the problem, i.e., they aren't used together for the same verification goal. And, making an educated guess, you're trying to say something about the maximum element of an array; where i is some sort of a loop-counter. The first line is what happens before the loop starts, and the second is the invariant the loop-body ensures. If this is the case, you should be explicit about that.
Assuming this is the case, then these sorts of problems are usually modeled on the "body" of that loop, i.e., you need to show us exactly what sort of a "program" you're dealing with. That is, these constraints will only make sense in the presence of some sort of a transformation of your program variables.
The Cubical Agda library defined a Modulo type like this:
data Modulo (k : ℕ) : Type₀ where
embed : (n : ℕ) → Modulo k
pre-step : NonZero k → (n : ℕ) → embed n ≡ embed (k + n)
Is this a Set?
Hand-wavingly, I can see that any path is a composition of refls and pre-steps, taking the form embed n ≡ embed (m * k + n); and
since _+_ is associative and 0 +_ ≡ id, the structure of how refls and pre-steps are combined doesn't matter; but how would that be formalized?
Based on #András Kovács's comment, turns out Modulo n is indeed a h-set and there is a proof in the standard library, I just missed it :)
The proof basically goes like this:
Modulo 0 is isomorphic to ℕ since NonZero 0 is empty (so we only have embed values).
Modulo (suc k) is isomorphic to Fin (suc k) basically by applying enough pre-steps until we get embed n with n < k. This is a long-winded technical proof taking up its own module.
And then of course both ℕ and Fin (suc k) are discrete, hence h-sets themselves.
I want to prove that there exist a natural number which is less than 10. I write the code in this way..
thm2 : (∃ λ m → (m < 10))
thm2 = zero , s≤s z≤n
I am not able to understand how this is working. Please explain..
Let's dissect thm2.
The type of the expression
∃ λ m → m < 10
∃ is defined in Data.Product as an alias for Σ where the first argument is left implicit. This means that ∃ is taking an element B of type A → Set and returning the type of pairs containing an a of type A and a b of type B a.
Now, λ m → m < 10 is taking an m in ℕ and returning the type of proofs that m < 10.
So ∃ λ m → m < 10 is the type of pairs of an ℕ and a proof that it is less than 10.
The expression itself
zero , s≤s z≤n
For the whole thing to typecheck, we need:
zero to be a ℕ which it is.
s≤s z≤n to be a proof that 0 < 10. _<_ is defined in Data.Nat.Base as an alias for λ m n → suc m ≤ n. So proving that 0 < 10 is the same as proving that 1 ≤ 10.
Now, _≤_ is an inductive type with two constructors:
a base case z≤n saying that 0 is less than or equal to all natural numbers
a step case s≤s saying that if one number is less than or equal to another, then their sucs also are less than or equal.
The proof s≤s z≤n is indeed a valid proof that 1 ≤ 10: z≤n proves that 0 ≤ 9 and s≤s concludes that therefore 1 ≤ 10.
I wanted to implement this statement in agda ;
A dedekind cut is a pair (L, U) of mere predicates L : Q -> Set and R : Q -> Set which is
1) inhibited : exists (q : Q) . L(q) ^ exists (r : Q) . U(r)
I have tried in this way,
record cut : Set where
field
L : Q -> Set
R : Q -> Set
inhibited : exists (q : Q) . L(q) ^ exists (r : Q) . U(r)
but this is not working. I want to write this and i am struck please help. And also what is the difference between 1)data R : Set and record R : Set and 2) data R : Set and data R : Q -> Set
I don't know about defining the whole of the dedekind cut, though I did find your definition on page 369 of Homotopy Type Theory: Univalent Foundations of Mathematics.
Here is the syntax for defining what you asked about in your question in two forms, one using the standard library and one expanded out to show what it is doing.
open import Data.Product using (∃)
record Cut (Q : Set) : Set₁ where
field
L U : Q → Set -- The two predicates
L-inhabited : ∃ L
U-inhabited : ∃ U
If we manually expand the definition of ∃ (exists) we have:
record Cut′ (Q : Set) : Set₁ where
field
L U : Q → Set -- The two predicates
q r : Q -- Witnesses
Lq : L q -- Witness satisfies predicate
Ur : U r -- Witness satisfies predicate
Note that the record has type Set₁ due to the types of fields L and U.
Regarding your question about records and inductively defined data types, there are lots of differences. You might want to start with the wiki and ask more specific questions if you get stuck somewhere: Data, Records
I found that there is a || in list manipulation. What does the || mean? Are there any examples about ||?
lists:sum([A*B || {A, B} <- Foo]).
It is used in List comprehensions. List comprehensions is a shorter way to create lists without having to use funs, maps or filters.
From Programming Erlang:
If we have a list L:
L = [1,2,3,4,5].
And we want to double every element, we can do:
lists:map(fun(X) -> 2*X end, L).
But with List comprehensions we can do:
[2*X || X <- L].
Nomenclature most likely comes from mathematical notion of sets, where || means "such that".
e.g. copied from Wikipedia
F = {n2 − 4 : n is an integer; and 0 ≤ n ≤ 19}
In this notation, the colon (":") means "such that", and the description can be interpreted as "F is the set of all numbers of the form n2 − 4, such that n is a whole number in the range from 0 to 19 inclusive." Sometimes the vertical bar ("|") is used instead of the colon.
Applying same thing to
lists:sum([A*B || {A, B} <- Foo]).
means:- generate A*B such that A and B belong to list of tuples "Foo"